java JVM 最大堆大小可以是动态的吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3472593/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can the JVM max heap size be dynamic?
提问by Electrons_Ahoy
The JVM -Xmx argument lets one set the max heap size for the JVM to some value. But, is there a way to make that value dynamic? In other words, I want to tell the JVM "look, if you need it, just keep taking RAM from the system until the system is out."
JVM -Xmx 参数允许将 JVM 的最大堆大小设置为某个值。但是,有没有办法使该值动态化?换句话说,我想告诉 JVM “看,如果你需要它,就继续从系统中获取 RAM,直到系统退出。”
Two-part reason for asking: First, the app in question can use a really wide range of ram depending on what the user is doing, so the conceptual min and max values are pretty far apart. Second, it would seem that the JVM reserves the max heap space from virtual memory at boot time. This particular app is run on a pretty wide variety of hardware, so picking a "one-size-fits-all" max heap space is hard since it has to be low enough to run on low-end hardware, but we'd really like to be able to take advantage of really beefy machines if they're available.
提出问题的两个部分原因:首先,有问题的应用程序可以使用非常广泛的内存,具体取决于用户正在做什么,因此概念上的最小值和最大值相距甚远。其次,JVM 似乎在启动时从虚拟内存中保留了最大堆空间。这个特定的应用程序在各种各样的硬件上运行,所以选择一个“一刀切”的最大堆空间是很困难的,因为它必须足够低才能在低端硬件上运行,但我们真的喜欢能够利用真正强大的机器(如果有的话)。
采纳答案by Stephen C
But, is there a way to make that value dynamic?
但是,有没有办法使该值动态化?
Literally, no. The max heap size is set at JVM launch time and cannot be increased.
从字面上看,没有。最大堆大小在 JVM 启动时设置,不能增加。
In practice, you couldjust set the max heap size to as large as your platform will allow, and let the JVM grow the heap as it needs. There is an obvious risk in doing this; i.e. that your application willuse all of the memory and cause the user's machine to grind to a halt. But that risk is implicit in your question.
在实践中,您可以将最大堆大小设置为平台允许的大小,并让 JVM 根据需要增加堆大小。这样做有明显的风险;即您的应用程序将使用所有内存并导致用户的机器停止工作。但这种风险隐含在你的问题中。
EDIT
编辑
It is worth noting that there are various -XX...GC tuning options that allow you to tweak the way that the JVM expands the heap (up to the maximum).
值得注意的是,有多种-XX...GC 调优选项允许您调整 JVM 扩展堆的方式(达到最大值)。
Another possibility is to split your application into 2 parts. The first part of the application does all of the preparation necessary to determine the "size" of the problem. Then it works out an appropriate max heap size, and launches the memory hungry second part of the application in a new JVM.
另一种可能性是将您的应用程序分成两部分。应用程序的第一部分完成了确定问题“大小”所需的所有准备工作。然后它计算出合适的最大堆大小,并在新的 JVM 中启动应用程序的内存饥渴的第二部分。
This only works if the application can sensibly be partitioned as above.
This only works if it is possible to compute the problem size. In some cases, computing the problem size is tantamount to computing the result.
It is not clear that you will get better overall performance than if you just let the heap grow up to a maximum size.
这仅在应用程序可以按上述方式进行合理分区时才有效。
这仅在可以计算问题大小时才有效。在某些情况下,计算问题大小就等于计算结果。
与让堆增长到最大大小相比,您是否会获得更好的整体性能尚不清楚。
回答by irreputable
It doesn't. It could, and it probably should:
它没有。它可以,而且可能应该:
-Xmx90% // 90% of physical memory
However, a default implicit, 100%, is proabbly not a good idea.
但是,默认的隐式 100% 可能不是一个好主意。
A program written in a non-GC language manages its memory very diligently, it will prune any garbage as soon as possible. It makes sense to allow it to get any memory it requests, assuming it's responsible for prompt garbage disposal.
用非 GC 语言编写的程序非常勤奋地管理其内存,它会尽快修剪任何垃圾。假设它负责及时处理垃圾,允许它获取它请求的任何内存是有意义的。
A GC language is different. It collects garbage only when necessary. As long as there's room, it doesn't care about garbage lingering around. If it could get all the memory it would like to have, it would get all the memory in the computer.
GC 语言是不同的。它仅在必要时收集垃圾。只要有空间,它就不会在意垃圾在周围徘徊。如果它可以获得它想要的所有内存,它就会获得计算机中的所有内存。
So a GC programmer doesn't have to worry about disposing every piece of garbage any more, but he still have to have a general idea of the tolerable garbage/live object ratio, and instruct GC with -Xmx.
所以GC程序员不用再操心处理每一块垃圾了,但还是要对可容忍垃圾/活对象比有个大概的概念,用-Xmx来指示GC。
回答by NoozNooz42
Basically, you can't adapt to various users' hardware using pure Java: that's when a little bit of shell/batch scripting can come in handy.
基本上,您无法使用纯 Java 来适应各种用户的硬件:这时,一点点 shell/批处理脚本就可以派上用场了。
I do just that on OS X and Linux: I've got a little bashshell script that takes care of finding the correct JVM parameters depending on the hardware the application is run on and then calling the JVM.
我只是在 OS X 和 Linux 上这样做:我有一个小bashshell 脚本,它负责根据运行应用程序的硬件找到正确的 JVM 参数,然后调用 JVM。
Note that if you're providing a desktop Java application, then you may want to use something like izpack to provide your users an installer:
请注意,如果您提供的是桌面 Java 应用程序,那么您可能希望使用 izpack 之类的工具为您的用户提供安装程序:
I don't know at all if Java Web Start can be used to provide different JVM parameters depending on the user's config (probably not, and JWS really s*cks big time anyway if you plan to provide a professional looking desktop app).
我完全不知道 Java Web Start 是否可用于根据用户的配置提供不同的 JVM 参数(可能不会,而且如果您打算提供专业外观的桌面应用程序,JWS 确实很花时间)。
回答by Tagar
There is a JDK Enhancement Proposal (JEP) 8204088
有一个 JDK 增强提案 (JEP) 8204088
"Dynamic Max Memory Limit"
“动态最大内存限制”
that suggests to introduce CurrentMaxHeapSize:
建议引入CurrentMaxHeapSize:
To dynamically limit how large the committed memory (i.e. the heap size) can grow, a new dynamically user-defined variable is introduced: CurrentMaxHeapSize. This variable (defined in bytes) limits how large the heap can be expanded. It can be set at launch time and changed at runtime. Regardless of when it is defined, it must always have a value equal or below to MaxHeapSize (Xmx - the launch time option that limits how large the heap can grow). Unlike MaxHeapSize, CurrentMaxHeapSize, can be dynamically changed at runtime.
The expected usage is to setup the JVM with a very conservative Xmx value (which is shown to have a very small impact on memory footprint) and then control how large the heap is using the CurrentMaxHeapSize dynamic limit.
为了动态限制提交的内存(即堆大小)可以增长的大小,引入了一个新的动态用户定义变量:CurrentMaxHeapSize。此变量(以字节为单位定义)限制了堆可以扩展的大小。它可以在启动时设置并在运行时更改。无论何时定义,它的值必须始终等于或小于 MaxHeapSize(Xmx - 限制堆可以增长多大的启动时间选项)。与 MaxHeapSize 不同,CurrentMaxHeapSize 可以在运行时动态更改。
预期用途是使用非常保守的 Xmx 值设置 JVM(这表明对内存占用的影响非常小),然后使用 CurrentMaxHeapSize 动态限制控制堆的大小。
While there are no signs of this feature actively being worked at, it's relatively new JEP (from 2018), so I would still keep this in mind.
虽然没有迹象表明此功能正在积极开发中,但它是相对较新的 JEP(从 2018 年开始),因此我仍会牢记这一点。
And company Jelastic (jelastic.com) has made a working prototype of JEP 8204088 for G1 garbage collector:
Jelastic 公司 (jelastic.com) 为 G1 垃圾收集器制作了 JEP 8204088 的工作原型:
See description at http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2018-May/022077.htmland list of patches for OpenJDK http://cr.openjdk.java.net/~tschatzl/jelastic/cmx/
请参阅http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2018-May/022077.html 上的描述 和 OpenJDK 的补丁列表 http://cr.openjdk.java.net/~tschatzl /果冻/cmx/

