-Xms和-Xms标志是否保留机器的资源?

Par*_*olu 14 java jvm

我知道-XmsJVM进程的标志是允许JVM进程使用特定数量的内存来初始化其进程.而对于Java应用程序的性能,通常建议设置为两个相同的价值观-Xms-Xmx启动应用程序时,喜欢-Xms2048M -Xmx2048M.

我很好奇-Xms-Xmx标志是否意味着JVM进程预留了特定的内存量以防止同一台机器中的其他进程使用它.

这是正确的吗?

the*_*472 7

Xmx仅保留虚拟地址空间. Xms实际上分配(提交)它但不一定是预先故障.

操作系统如何响应分配方式各不相同.

Windows确实允许您保留非常大的地址空间块(Xmx),但不允许过度使用(Xms).限制由swap + physical定义.例外是大页面(需要使用组策略设置启用),这将通过物理ram限制它.

Linux行为更复杂,它依赖于vm.overcommit_memory相关的sysctls和传递给mmap系统调用的各种标志,这在某种程度上可以通过JVM配置标志来控制.行为的范围可以从a)Xms可以超过总ram + swap到b)Xmx受可用物理ram的限制.

  • 有趣的...不应该`-XX:+ AlwaysPreTouch`在使用时预先存储内存? (3认同)
  • @尤金当然,因此“不一定” (2认同)

小智 5

JVM 进程是否会预留特定的内存量?

是的,JVM 保留了Xms开始时指定的内存,可能会保留 uptoXmx但保留不一定在物理内存中,它也可以在交换中。JVM 页面将根据需要在内存中换入和换出。


为什么建议 Xms 和 Xmx 具有相同的值?

注意:设置XmsXmx通常建议用于机器专用于单个应用程序的生产系统(或者没有很多应用程序争用系统资源)。这并不概括它在任何地方都很好。

避免堆大小:

JVM 以Xms初始值指定的堆大小开始。当堆因应用程序分配对象而耗尽时。JVM 开始增加堆。每次 JVM 增加堆大小时,它都必须向操作系统请求额外的内存。这是一项耗时的操作,会导致 gc 暂停时间增加,从而导致请求的响应时间增加。

从长远来看,应用程序的行为:

尽管我不能一概而论,但从长远来看,许多应用程序最终会增长到最大堆值。这是从最大内存开始而不是随时间增长堆并产生不必要的堆大小调整开销的另一个原因。这就像要求应用程序在开始时占用它最终将占用的内存。

GC 数量: :

从小堆大小开始会导致垃圾收集更频繁。更大的堆大小会减少发生的 gc 次数,因为更多的内存可用于对象分配。但是必须注意,增加堆大小会增加 gc 暂停时间。只有当您的垃圾收集已正确调整并且暂停时间不会随着堆大小的增加而显着增加时,这才是一个优势。

这样做的另一个原因是服务器通常带有大量内存,那么为什么不使用可用资源呢?


Ash*_*uri 5

简短回答:取决于操作系统,尽管在所有流行的操作系统中它绝对不是。

我将在这里以 Linux 的内存分配术语为例。

-Xms 和 -Xmx 指定 JVM 堆的最小和最大大小。这些大小反映了虚拟内存分配,可以在任何时候物理映射到 RAM 中的页面,称为进程的驻留大小。

当 JVM 启动时,它会分配 -Xms 数量的虚拟内存。一旦您在堆上动态创建更多对象,这可以映射到常驻内存(物理内存)。此操作不需要 JVM 从操作系统请求任何新分配,但会增加您的 RAM 利用率,因为这些虚拟页面现在实际上也具有相应的物理内存分配。但是,一旦您的进程在消耗了 RAM 上的所有 Xms 分配后尝试在堆上创建更多对象,它就必须向操作系统请求更多来自操作系统的虚拟内存,这些虚拟内存可能/也可能不会映射到物理内存,具体取决于何时你需要它。对此的限制是您的 -Xmx 分配。

请注意,这一切都是可能的,因为 linux 中的内存是共享的。因此,即使一个进程事先分配了内存,它得到的只是虚拟内存,它只是一个可寻址的连续虚构分配,它可能会或可能不会映射到实际物理页面,具体取决于需求。阅读此答案以简要说明内存管理如何在流行的操作系统中工作。是有关 Linux 内存管理如何工作的详细信息(有点过时但非常有用)。

另请注意,这些标志仅影响堆大小。您将看到的常驻内存大小将大于当前的 JVM 堆大小。更具体地说,JVM 消耗的内存等于其 HEAP SIZE 加上 DIRECT MEMORY,这反映了来自方法堆栈、本机缓冲区分配等的内容。