我有一个作为服务器运行的java程序。 Java版本是Java6u35。操作系统是CentOS 6。
堆配置为-Xmx3g -Xms3g
。经过几天的运行,它分配了超过8G的内存并实际使用了超过6G的内存。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
26955 deploy 15 0 8347m 6.0g 10m S 30.9 25.5 3730:12 java
额外的内存肯定是堆内存。
使用pmap,我得到了以下内容。单位 k 。整个输出超出了stackoverflow问题体限制的限制,所以我删除了一些小的。从大小1016k开始。 (有超过300行有类似内容address 1,016 rwx-- [anon]
):
addres size(kB)
0000000063ba3000 1,016 rwx-- [anon] (over 300 similar lines omitted)
00002aaaaaac3000 1,020 ----- /usr/java/jdk1.6.0_35/jre/lib/amd64/libverify.so
00002aaaaabee000 1,020 ----- /usr/java/jdk1.6.0_35/jre/lib/amd64/libjava.so
00002aaaaad2c000 1,020 ----- /usr/java/jdk1.6.0_35/jre/lib/amd64/libjdwp.so
00002aaaaae38000 1,020 ----- /usr/java/jdk1.6.0_35/jre/lib/amd64/libnpt.so
00002aaab76b1000 1,020 ----- /usr/java/jdk1.6.0_35/jre/lib/amd64/libdt_socket.so
00002aaab77b8000 1,020 ----- /usr/java/jdk1.6.0_35/jre/lib/amd64/libmanagement.so
00002aaab842b000 1,020 ----- /usr/java/jdk1.6.0_35/jre/lib/amd64/libnio.so
00002aaab8748000 1,020 ----- /usr/java/jdk1.6.0_35/jre/lib/amd64/libjaas_unix.so
00002aab87519000 1,020 ----- /usr/java/jdk1.6.0_35/jre/lib/amd64/librmi.so
00000000411ec000 1,024 rwx-- [anon]
00000000412ed000 1,024 rwx-- [anon]
0000000041ad8000 1,024 rwx-- [anon]
0000000041bd9000 1,024 rwx-- [anon]
0000000041cda000 1,024 rwx-- [anon]
0000000041ddb000 1,024 rwx-- [anon]
0000000041edc000 1,024 rwx-- [anon]
0000000041fdd000 1,024 rwx-- [anon]
00000000420de000 1,024 rwx-- [anon]
00000000421df000 1,024 rwx-- [anon]
4.22E+02 1,024 rwx-- [anon]
00000000423e1000 1,024 rwx-- [anon]
00000000428e6000 1,024 rwx-- [anon]
00002b66d5a07000 1,024 ----- /usr/java/jdk1.6.0_35/jre/lib/amd64/server/libjvm.so
00002aaab78cc000 1,028 ----- /usr/java/jdk1.6.0_35/jre/lib/amd64/libnet.so
00002b66d4fe5000 1,028 ----- /usr/java/jdk1.6.0_35/jre/lib/amd64/jli/libjli.so
00002aaaae72f000 1,032 ----- /usr/java/jdk1.6.0_35/jre/lib/amd64/libzip.so
00002aab83efd000 1,036 ----- [anon]
00002aabbfefd000 1,036 ----- [anon]
00000038b5600000 1,340 r-x-- /lib64/libc-2.5.so
00002aaacfe95000 1,452 ----- [anon]
00002aaab74e3000 1,628 r-xs- /usr/java/jdk1.6.0_35/jre/lib/rt.jar
00002b66d5b07000 1,752 rwx-- /usr/java/jdk1.6.0_35/jre/lib/amd64/server/libjvm.so
00000038b574f000 2,044 ----- /lib64/libc-2.5.so
00000038b5e16000 2,044 ----- /lib64/libpthread-2.5.so
00000038b6a82000 2,044 ----- /lib64/libm-2.5.so
00000038b9a15000 2,044 ----- /lib64/libnsl-2.5.so
00002aaaae520000 2,044 ----- /lib64/libnss_files-2.5.so
00002aaab8223000 2,044 ----- /lib64/libnss_dns-2.5.so
00000038b5a02000 2,048 ----- /lib64/libdl-2.5.so
00000038b7207000 2,048 ----- /lib64/librt-2.5.so
00000038b8211000 2,048 ----- /lib64/libresolv-2.5.so
00002aaab8546000 2,048 ----- /SERVER/lib/native/libhadoop.so
00002aaab79d0000 3,076 rwx-- [anon]
00002aabd3b22000 4,984 ----- [anon]
00002aaab18f5000 6,400 rwx-- [anon]
00002aaaae834000 7,940 rwx-- [anon]
ffffffffff600000 8,192 ----- [anon]
00002b66d50eb000 9,328 r-x-- /usr/java/jdk1.6.0_35/jre/lib/amd64/server/libjvm.so
00002aaac8000000 18,180 rwx-- [anon]
00002aabcc000000 28,724 rwx-- [anon]
00002aabcdc0d000 36,812 ----- [anon]
00002aaaaeff5000 41,216 rwx-- [anon]
00002aaac91c1000 47,356 ----- [anon]
00002aab84000000 54,368 rwx-- [anon]
00002aaaaaf38000 55,120 r-x-- /usr/lib/locale/locale-archive
00002aaab884c000 56,784 rwx-- [anon]
00002aabd0000000 60,552 rwx-- [anon]
00002aaacc000000 64,084 rwx-- [anon]
00002aab80000000 64,500 rwx-- [anon]
00002aabbc000000 64,500 rwx-- [anon]
00002aab14000000 64,576 rwx-- [anon]
00002aab64000000 64,584 rwx-- [anon]
00002aab90000000 64,668 rwx-- [anon]
00002aabac000000 64,684 rwx-- [anon]
00002aab88000000 64,692 rwx-- [anon]
00002aabc4000000 64,716 rwx-- [anon]
00002aab18000000 64,836 rwx-- [anon]
00002aab48000000 64,868 rwx-- [anon]
00002aabc0000000 64,896 rwx-- [anon]
00002aabb4000000 64,936 rwx-- [anon]
00002aabb8000000 64,948 rwx-- [anon]
00002aab94000000 64,976 rwx-- [anon]
00002aab1c000000 65,008 rwx-- [anon]
00002aabb0000000 65,020 rwx-- [anon]
00002aaaf8000000 65,032 rwx-- [anon]
00002aaabc000000 65,152 rwx-- [anon]
00002aab98000000 65,184 rwx-- [anon]
00002aaba0000000 65,320 rwx-- [anon]
00002aab8c000000 65,360 rwx-- [anon]
00002aaac0000000 65,388 rwx-- [anon]
00002aaba8000000 65,440 rwx-- [anon]
00002aaba4000000 65,472 rwx-- [anon]
00002aaac4000000 65,508 rwx-- [anon]
00002aab9c000000 65,508 rwx-- [anon]
00002aaab1f35000 87,736 rwx-- [anon]
000000004a74f000 104,592 rwx-- [anon]
00002aaafc000000 392,432 rwx-- [anon]
00002aab4c000000 392,480 rwx-- [anon]
00002aab68000000 392,908 rwx-- [anon]
00002aab20000000 654,464 rwx-- [anon]
00002aaad0000000 655,072 rwx-- [anon]
738000000 3,276,800 rwx-- [anon]
total 8,551,872
使用此工具检查直接内存使用量https://gist.github.com/rednaxelafx/1593521:
JVM version is 20.10-b01
NIO direct memory: (in bytes)
reserved size = 228.038025 MB (239115200 bytes)
max size = 2867.250000 MB (3006529536 bytes)
所以直接记忆不是太大。 3,276,800
是java堆。但找不到谁需要数百MB的内存。
此服务器程序使用hadoop客户端,hbase客户端将数据写入hadoop和hbase。 java Heap它自己工作得很好。
任何线索都表示赞赏。
答案 0 :(得分:7)
找出解决方案,但原因仍然是黑盒子。添加-XX:MaxDirectMemorySize=1024m
后,它就可以了。
似乎java GC for Memory Outside Heap(MOH)并不像heap gc那么聪明。
猜测的原因是,当MOH使用达到某个水平,可能是50%时触发MOH的java gc。所以在此之前,它只会将内存标记为已释放但实际上并非自由。即使系统内存也很少。
默认情况下,XX:MaxDirectMemorySize很大,甚至使用率为50%,系统也会关闭。
因此,在添加此限制后,阈值很容易达到,并且MOH会及时释放。
所以1024m
适用于我的应用程序。它足以让应用程序运行而不会太大而不会使系统崩溃。