我的系统无法为Java进程提供超过1.5 Gb的系统。因此,我需要一种确切的方法来指定java进程设置,包括java内部的所有内存种类和可能的fork。
一个特定的java进程和系统来说明我的问题:
我目前的环境是Ubuntu Linux 9.10下的java 1.6.0_18。
我使用以下JVM选项启动大型Java服务器进程: “-Xms512m -Xmx1024m -XX:PermSize = 256m -XX:MaxPermSize = 512m”
现在,“top”命令报告该进程使用1.6gb内存...
问题:
1 - 如何计算java进程使用的最大空间?如果可能,请提供准确的公式。 (Smth。赞:max.heap + max.perm + stack + jvm space = maximal space)
2 - 在我的情况下linux下臭名昭着的fork行为是什么?分叉的JVM是否会占用额外的1.6 gb(导致总共3.2 Gb的已用内存)?
3 - 必须使用哪些选项来绝对确保在任何时候使用不超过1.5gb?
谢谢
@rancidfishbreath:“ulimit”将确保java不能占用超过指定数量的内存。我的目的是确保java不会尝试这样做。答案 0 :(得分:3)
top 报告1.6GB,因为PermSize是堆大小最大堆大小的ON TOP。在您的情况下,您将MaxPermSize设置为512m,将Xmx设置为1024m。这相当于1536米。就像在其他语言中一样,除非您确切地知道启动了多少个线程,使用了多少个文件句柄等,否则无法计算绝对精确的数字。每个线程的堆栈大小取决于操作系统和JDK版本,在您的情况下, 1024k(如果是64位机器)。因此,如果您有10个线程,则使用10240k额外,因为堆栈未从堆中分配(Xmx)。大多数应用程序在设置较低堆栈和MaxPermSize时表现良好。尝试将ThreadStackSize设置为128k,如果得到StackOverflowError(即如果你进行了很多深度递归),可以稍微增加它,直到问题消失为止。
所以我的答案基本上是你无法控制它到MB的程序将使用多少Java,但你通过设置ie -Xmx1024m -XX来接近:MaxPermSize = 384m和-XX:ThreadStackSize = 128k - XX:+ UseCompressedOops。即使你有很多线程,你仍然会有足够的余量,直到达到1.5GB。 UseCompressedOops告诉VM即使在64位JVM上运行也使用窄指针,从而节省了一些内存。
答案 1 :(得分:1)
在高级JVM地址空间分为三个主要部分:
-Xmx
,-XX:MaxPermSize
等指定的Java堆... 所以你有(4GB - 内核空间1-1.25GB)~2.75GB可以玩,所以你可以相应地设置你的java / native堆。但是通常我们应该为JVM本机堆保留至少500MB,否则你有机会获得本机OOM。因此,我们需要根据您的应用程序的Java堆利用率进行权衡。