我在使用内存控件的环境中运行java时遇到了一些问题。我的用例是sun grid engine(SGE),但是我可以用ulimit进行复制。
当我试图在内存有限制的情况下运行java时,我发现仍然需要允许ulimit提供更大的内存量。
evaben@evaben:~$ (ulimit -v 1000000; java -Xmx500m -version; )
Error occurred during initialization of VM
Could not allocate metaspace: 1073741824 bytes
evaben@evaben:~$ (ulimit -v 2000000; java -Xmx500m -version; )
Error occurred during initialization of VM
Could not allocate metaspace: 1073741824 bytes
evaben@evaben:~$ (ulimit -v 4000000; java -Xmx500m -version; )
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-2ubuntu0.18.04.1-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
evaben@evaben:~$
所以500米的-Xmx需要ulimit的4G空间。我知道Xmx只限制了java内存使用的某些方面,可能只是堆。但3.5G或700%的开销似乎过高。
我试过一些策略,我看到上面的java正在映射多个大的块,可能来自不同的线程或子进程。
strace -f -e memory java -Xmx500M -version 2>&1 1>/dev/null | grep mmap | grep ENOMEM | wc -l
96
strace -f -e memory java -Xmx500M -version 2>&1 1>/dev/null | grep mmap | awk '$1 == "[pid"{print $2}' | sort | uniq -c
> many pids mmapping
/bin/time只报告RSS,在本例中大约为30mbytes。有没有一种简单的方法来显示全部alloc/mmap请求?
为什么java需要这么多内存?有没有什么方法可以让java在更少内存分配的情况下运行?