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

Dim*_*rov 5 java jvm memory-management

我有一个系统不能为 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. Like: max.heap + max.perm + stack + jvm space = maximal space )

2 - 就我而言,Linux 下臭名昭著的分叉行为是什么?分叉的 JVM 会占用额外的 1.6 GB(导致总共 3.2 Gb 的已用内存)吗?

3 - 必须使用哪些选项才能绝对确保任何时候使用的内存不超过 1.5GB?

谢谢你

@rancidfishbreath:“ulimit”将确保java不能占用超过指定数量的内存。我的目的是确保 java 永远不会尝试这样做。

SiC*_*iCN 3

top报告 1.6GB,因为 PermSize 位于堆大小最大堆大小之上。在您的情况下,您将 MaxPermSize 设置为 512m,将 Xmx 设置为 1024m。这总计 1536m。就像在其他语言中一样,除非您确切地知道启动了多少个线程、使用了多少个文件句柄等,否则无法计算出绝对精确的数字。每个线程的堆栈大小取决于操作系统和 JDK 版本,在您的情况下,它是1024k(如果是64位机器)。因此,如果您有 10 个线程,则需要额外使用 10240k,因为堆栈不是从堆 (Xmx) 分配的。大多数表现良好的应用程序在设置较低的堆栈和 MaxPermSize 时都能完美运行。尝试将 ThreadStackSize 设置为 128k,如果出现 StackOverflowError(即,如果执行大量深度递归),则可以小步增加它,直到问题消失。

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