【问题标题】:How to calculate (and specify) the total memory space allowed for java process?如何计算(并指定)java进程允许的总内存空间?
【发布时间】:2011-03-31 15:28:33
【问题描述】:

我有一个不能为 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 空间 = 最大空间)

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

3 - 必须使用哪些选项来绝对确保在任何时候使用不超过 1.5gb?

谢谢

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

【问题讨论】:

  • 我无法回答前两个问题,但您应该查看 ulimit 以帮助您解决第三个问题。 Ulimit 不是跨平台的,但它会在 Linux 下为您提供帮助。

标签: java jvm memory-management


【解决方案1】:

top 报告 1.6GB,因为 PermSize 在堆大小的最大堆大小之上。在您的情况下,您将 MaxPermSize 设置为 512m,将 Xmx 设置为 1024m。这相当于1536m。就像在其他语言中一样,除非您确切知道启动了多少线程、使用了多少文件句柄等,否则无法计算出绝对精确的数字。每个线程的堆栈大小取决于操作系统和 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 上运行时也使用窄指针,从而节省一些内存。

【讨论】:

  • 这对我有进一步的帮助。谢谢sicn
【解决方案2】:

在高层次上,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 堆利用率做一个权衡。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 2011-10-27
    • 2021-07-08
    • 2014-03-26
    • 2011-09-05
    • 2014-07-13
    相关资源
    最近更新 更多