默认的最大Java堆大小是如何确定的?

如果我从Java命令行中省略-Xmxn选项,则将使用默认值。根据Java文档

在运行时根据系统配置选择默认值。

哪些系统配置设置会影响默认值?

434546 次浏览

对于Java SE 5:根据垃圾收集器人机工程学[Oracle]:

初始堆大小:

大于机器物理内存的1/64 合理的最低。在J2SE 5.0之前, 默认的初始堆大小为 合理的最小值,由 平台。你可以重写这个 默认使用-Xms命令行 选择。< / p >

最大堆大小:

小于物理内存的1/4或1GB。在J2SE 5.0之前, 默认最大堆大小为64MB。 您可以使用 -Xmx命令行选项

更新:

正如Tom Anderson在他的评论中所指出的,以上是针对服务器级机器的。从5.0 JavaTM虚拟机中的人机工程学:

在J2SE平台5.0版本中 机器类称为a类 服务器类机器已经定义 作为

的机器
  • 2个或更多物理处理器
  • 2或更多gb的物理内存

, 32位平台除外 运行Windows的一个版本 操作系统。在所有其他 平台默认值为 与版本的默认值相同 1.4.2. < / p >

在J2SE平台1.4.2版本中 默认情况下,以下选择为 了< / p >

  • 初始堆大小为4 Mbyte
  • 最大堆大小为64 Mbyte

这在Java 6更新18中被改变。

假设我们有超过1 GB的物理内存(现在很常见),它总是服务器vm的物理内存的1/4。

欧内斯托是对的。根据他发布的链接[1]:

更新客户端JVM堆配置

在客户端JVM中…

  • 默认的最大堆大小是物理内存的一半,物理内存大小不超过192兆字节,否则是物理内存的四分之一,物理内存大小不超过1gb。

    例如,如果您的机器有128兆的物理内存,那么最大堆大小是64兆,大于或等于1gb的物理内存导致最大堆大小为256兆

  • JVM实际上并不使用最大堆大小,除非您的程序创建了足够多的对象来需要它。在JVM初始化. ...期间分配的量要小得多,称为初始堆大小

  • ...
  • 服务器JVM堆配置的人机工程学现在与客户端相同,除了32位jvm的默认最大堆大小是1gb(对应于4 gb的物理内存大小)和64位jvm是32g(对应于128 gb的物理内存大小)。

[1] http://www.oracle.com/technetwork/java/javase/6u18-142093.html

在Windows上,可以使用以下命令找出运行应用程序的系统上的默认值。

java -XX:+PrintFlagsFinal -version | findstr HeapSize

寻找选项MaxHeapSize(用于-Xmx)和InitialHeapSize用于-Xms

在Unix/Linux系统上,您可以这样做

java -XX:+PrintFlagsFinal -version | grep HeapSize

我认为结果输出是以字节为单位的。

对于IBM JVM,命令如下:

java -verbose:sizes -version

有关Java 8的IBM SDK的更多信息:http://www-01.ibm.com/support/knowledgecenter/SSYKE2_8.0.0/com.ibm.java.lnx.80.doc/diag/appendixes/defaults.html?lang=en

在运行时根据系统配置选择默认值

看看文档页面

默认堆大小

除非在命令行上指定了初始和最大堆大小,否则它们将根据计算机上的内存量计算。

  1. 客户端JVM默认初始和最大堆大小:

    默认的最大堆大小是物理内存的一半,最大物理内存大小为192兆字节(MB),否则是物理内存的四分之一,最大物理内存大小为1gb

  2. 服务器JVM默认初始和最大堆大小:

    在32位jvm上,如果有4gb或更多的物理内存,默认的最大堆大小可以达到1gb在64位jvm上,如果有128 GB或更多的物理内存,那么默认的最大堆大小可以达到32 GB

哪些系统配置设置会影响默认值?

你可以使用标记< >强xms < / >强(初始堆大小)和< >强- xmx < / >强(最大堆大小)指定初始和最大堆大小。如果你知道你的应用程序需要多少堆才能正常工作,你可以将< >强xms < / >强< >强- xmx < / >强设置为相同的值

Java 8为你的Xmssize(最小堆大小)占用了超过1/64th的物理内存,为你的-Xmxsize(最大堆大小)占用了小于1/4th的物理内存。

你可以通过以下方法检查默认Java堆大小:

窗户:

java -XX:+PrintFlagsFinal -version | findstr /i "HeapSize PermSize ThreadStackSize"

Linux:

java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'

哪些系统配置设置会影响默认值?

机器的物理内存&Java版本。

有许多参数影响生成大小。下图说明了堆中提交空间和虚拟空间之间的区别。在初始化虚拟机时,将为堆保留整个空间。预留空间的大小可以通过-Xmx选项指定。如果-Xms参数的值小于-Xmx参数的值,则不是所有预留的空间都立即提交给虚拟机。在这个图中,未提交的空间被标记为“virtual”。堆的不同部分(永久代、年老代和年轻代)可以根据需要增长到虚拟空间的极限。

enter image description here

默认情况下,虚拟机会增加或缩小每个集合的堆,以尽量将每个集合的空闲空间与活动对象的比例保持在特定的范围内。这个目标范围由参数-XX:MinHeapFreeRatio=<minimum>-XX:MaxHeapFreeRatio=<maximum>设置为一个百分比,总大小的下限为-Xms<min>,上限为-Xmx<max>

参数默认值

MinHeapFreeRatio 40

MaxHeapFreeRatio 70

xms 3670 k

- xmx 64

64位系统上堆大小参数的默认值增加了大约30%。这种增加是为了弥补64位系统中对象的较大大小。

使用这些参数,如果代中的空闲空间百分比低于40%,则将扩展代以保持40%的空闲空间,直到允许的最大代大小。同样,如果自由空间超过70%,则代将收缩,以只有70%的空间是自由的,这取决于代的最小大小。

大型服务器应用程序使用这些默认值时经常遇到两个问题。一个是启动缓慢,因为初始堆很小,必须在许多主要集合中调整大小。一个更紧迫的问题是,对于大多数服务器应用程序来说,默认的最大堆大小小得不合理。服务器应用程序的经验法则是:

  • 除非你有暂停的问题,尝试授予尽可能多的内存 可能对虚拟机。默认大小(64MB)通常也是 李小。< / >
  • 将-Xms和-Xmx设置为相同的值将增加可预测性 从虚拟机中删除最重要的大小决定。 但是,虚拟机随后无法补偿,如果您做出
  • 一般情况下,增加内存的数量 处理器,因为分配可以并行化

    全文

XmsXmx是Java虚拟机(JVM)的标志:

  • Xms: initial and minimum JVM heap size
    • Format: -Xms<size>[g|G|m|M|k|K]
    • <李> Default Size:
      • -server模式:25%的空闲物理内存,>=8MB and <= 64MB
      • -client mode: 25%的可用物理内存,>=8MB and <= 16MB
      <李> Typical Size:
      • -Xms128M
      • -Xms256M
      • -Xms512M
      <李> Function / Effect:
      • →JVM开始分配Xms大小的内存
  • Xmx: maximum JVM heap size
    • Format: -Xmx<size>[g|G|m|M|k|K]
    • <李> Default Size:
        <李> <= R27.2
        • Windows:到1GB的总物理内存的75%
        • Linux/Solaris:到1GB的可用物理内存的50%
        <李> >= R27.3
        • Windows X64:到2GB的总物理内存的75%
        • Linux/Solaris X64:到2GB的可用物理内存的50%
        • Windows x86:到1GB的总物理内存的75%
        • Linux/Solaris X86:到1GB的可用物理内存的50%
      <李> Typical Size:
      • -Xmx1g
      • -Xmx2084M
      • -Xmx4g
      • -Xmx6g
      • -Xmx8g
      <李> Function / Effect:
        <李>→JVM允许使用最大Xmx大小的内存
        • 当超过Xmx时,将java.lang.OutOfMemoryError
          • 如何修复OutOfMemoryError ?
            • 超过Xmx
              • -Xmx4g-Xmx8g

更详细地

参见官方文档:-X命令行选项

终于!

从Java 8u191开始,你现在有以下选项:

-XX:InitialRAMPercentage
-XX:MaxRAMPercentage
-XX:MinRAMPercentage

可用于按可用物理RAM的百分比来确定堆的大小。(这与安装的RAM比内核使用的少)。

更多信息请参见Java8 u191的发布说明。请注意,这些选项是在Docker标题下提到的,但实际上无论您是在Docker环境中还是在传统环境中,它们都适用。

MaxRAMPercentage的默认值是25%。这是极端保守的。

我自己的原则是:如果您的主机或多或少致力于运行给定的java应用程序,那么您可以毫无问题地大幅增加。如果你在Linux上,只运行标准的守护进程,并且安装了大约1gb以上的RAM,那么我会毫不犹豫地将75%的内存用于JVM堆。同样,记住这是RAM 可用的75%,而不是RAM 安装。剩下的是可能在主机上运行的其他用户空间进程和JVM需要的其他类型的内存(例如堆栈)。总的来说,这将非常适合剩下的25%。显然,有了更多的内存安装,75%是一个更安全的赌注。(我希望JDK的人已经实现了一个选项,你可以指定一个梯子)

设置MaxRAMPercentage选项如下所示:

java -XX:MaxRAMPercentage=75.0  ....

注意,这些百分比值是“double”类型,因此你必须用一个小数点来指定它们。如果使用“75”而不是“75.0”,就会得到一个有点奇怪的错误。