我在具有内存控件的环境中运行Java时遇到一些问题。我的用例是Sun Grid Engine(SGE),但我可以使用ulimit复制。
当我尝试以内存限制(-Xmx)运行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:~$
因此,一个500m的-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,在此示例中约为30 MB。有没有一种简单的方法可以显示总的alloc / mmap请求?
为什么Java需要那么多内存?有什么方法可以让Java在更少的内存分配下运行?