如何计算(和指定)java进程允许的总内存空间?

我有一个系统,它不能为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不会尝试这样做。

top报告1.6GB,因为PermSize是堆大小最大堆大小的ON TOP。 在您的情况下,您将MaxPermSize设置为512m,将Xmx设置为1024m。 这相当于1536米。 就像在其他语言中一样,除非您准确知道启动了多少个线程,使用了多少个文件句柄等,否则无法计算绝对精确的数字。每个线程的堆栈大小取决于操作系统和JDK版本,在您的情况下, 1024k(如果它是64位机器)。 因此,如果您有10个线程,则使用10240k extra,因为堆栈未从堆中分配(Xmx)。 大多数应用程序在设置较低堆栈和MaxPermSize时表现良好。 尝试将ThreadStackSize设置为128k,如果得到StackOverflowError(即如果你进行了很多深度递归),可以稍微增加它,直到问题消失。

所以我的答案基本上是你无法控制它到MB将使用多少Java进程,但你通过设置ie -Xmx1024m -XX来接近:MaxPermSize = 384m和-XX:ThreadStackSize = 128k -XX:+ UseCompressedOops。 即使你有很multithreading,你仍然有足够的空间,直到达到1.5GB。 UseCompressedOops告诉VM即使在64位JVM上运行也使用窄指针,从而节省了一些内存。

在高级别JVM地址空间分为三个主要部分:

  1. 内核空间: ~1GB,也取决于平台,windows超过1GB
  2. Java堆:用户使用-Xmx-XX:MaxPermSize等指定的Java堆…
  3. 其余的虚拟地址空间用于JVM的本机使用,以容纳由JVM完成的malloc / calloc,本机线程堆栈:线程相应的java线程和GC的附加JVM本机线程等…

所以你有(4GB – 内核空间1-1.25GB)~2.75GB可以玩,所以你可以相应地设置你的java / native堆。 但是通常我们应该为JVM本机堆保留至少500MB,否则你有机会获得本机OOM。 因此,我们需要根据您的应用程序的Java堆利用率进行权衡。