2014-07-10 127 views
2

我在一台机器(Ram大小为16GB)中运行两个tomcat服务器,其内存设置如下。Java进程占用的内存大于其最大堆大小

JAVA_MEM_OPTIONS="-Xmx4096M -Xms4096M -XX:NewSize=512M -XX:MaxNewSize=512M -XX:PermSize=256M -XX:MaxPermSize=256M -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime -XX:SoftRefLRUPolicyMSPerMB=5 -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC" 

顶结果显示存储器46.5%(7.44 GB)& 39.2%(6.24 GB)由java程序使用。

Tasks: 120 total, 1 running, 119 sleeping, 0 stopped, 0 zombie 
Cpu(s): 7.8%us, 0.4%sy, 0.0%ni, 90.9%id, 0.2%wa, 0.0%hi, 0.7%si, 0.0%st 
Mem: 16424048k total, 16326072k used, 97976k free, 28868k buffers 
Swap: 1959920k total, 1957932k used,  1988k free, 1082276k cached 

PID USER  PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND                                   
26275 user1  25 0 8007m 7.3g 7832 S 13.6 46.5 785:31.89 java                                    
28050 user2  25 0 7731m 6.1g 13m S 9.0 39.2 817:10.47 java 

GC日志显示每个java进程只使用4GB的内存。一旦系统内存使用量上升,它永远不会下降。

user1 - java process 

89224.492: [GC 89224.492: [ParNew: 443819K->17796K(471872K), 0.0367070 secs] 2032217K->1608465K(4141888K), 0.0368920 secs] [Times: user=0.13 sys=0.00, real=0.03 secs] 
89228.247: [GC 89228.247: [ParNew: 437252K->22219K(471872K), 0.0607080 secs] 2027921K->1615327K(4141888K), 0.0609240 secs] [Times: user=0.15 sys=0.00, real=0.06 secs] 

user2 - java process 

89202.170: [GC 89202.170: [ParNew: 444989K->22909K(471872K), 0.0510290 secs] 2361057K->1945258K(4141888K), 0.0512370 secs] [Times: user=0.19 sys=0.00, real=0.05 secs] 
89207.894: [GC 89207.894: [ParNew: 442365K->15912K(471872K), 0.0422190 secs] 2364714K->1945162K(4141888K), 0.0424260 secs] [Times: user=0.15 sys=0.00, real=0.04 secs] 

当堆内存设置为4GB时,java进程如何使用这么多的内存。如何调试问题的原因。

PS:有时我正在从java代码执行shell脚本。会导致这种问题吗?

+0

Java进程不仅具有堆。还有其他的东西要存储。 – Henry

+0

可能的重复候选人:http://stackoverflow.com/questions/10818356/java-process-memory-is-much-bigger-than-specified-limits,http://stackoverflow.com/questions/6527131/java-using更多的内存比分配内存,http://stackoverflow.com/questions/11768615/jvm-memory-usage-out-of-control,http://stackoverflow.com/questions/9145769/limit -jvm进程存储器-上的ubuntu –

回答

2

有以下几种情况:

  1. 拥有大量线程的。线程堆栈空间分配在堆/ perm空间之外。要设置为每个线程分配的内存,请使用-Xss选项。
  2. 使用JNI。看看这个问题Java app calls C++ DLL via JNI; how best to allocate memory?

也许还有更多,在实践中,第一种情况最有可能的原因。