Java 堆大小未完全使用
我目前正在使用 Visual VM 监视正在运行的 java 应用程序: http://visualvm.java.net/
我通过 -Xmx128m 强调内存使用情况。
运行时,我看到堆大小增加到 128m(如预期),但是在遇到 java 堆空间错误之前,已用堆收敛到大约 105m。
为什么剩下的 20m 没有使用?
I'm currently monitoring my running java application with Visual VM: http://visualvm.java.net/
I'm stressing the memory usage by with -Xmx128m.
When running I see the heap size increasing to 128m (as expected) however the used heap converges to approximately 105m before I run into a java heap space error.
Why are these remaining 20m, not used?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您需要了解有关垃圾收集器人体工程学的一个核心事实:
这意味着:当堆接近其最大容量时,GC将花费越来越多的时间,而回收的空间回报却越来越少。如果 GC 尝试使用内存的最后一个字节,最终结果将是您的 JVM 将花费越来越多的时间进行垃圾收集,直到……最终……几乎没有完成任何有用的工作。
为了避免这种病态情况,JVM 会监视 GC 和执行有用工作所花费的时间比率。当该比率超过可配置的阈值时,GC 会引发
OutOfMemoryError
...即使(技术上)有可用的空闲内存。这可能就是您所看到的,尽管其他解释同样合理。您可以通过 JVM 选项更改 GC 阈值、生成大小等,但最好不要这样做。更好的想法是找出应用程序的内存使用量不断上升的原因。您的代码中很可能存在内存泄漏...即错误...导致了这种情况。花精力查找并修复这些错误,而不是担心为什么没有使用所有内存。
(事实上,你正在使用它......但并非一直如此。)
You need to understand a central fact about garbage collector ergonomics:
This means: as the heap gets close to its maximum capacity, the GC will spend more and more time for less and less return in reclaimed space. If the GC was to try and use every last byte of memory, the net result would be that your JVM would spend more and more time garbage collecting, until ... eventually ... almost no useful work was being done.
To avoid this pathological situation, the JVM monitors the ratio of time is spent GC'ing and doing useful work. When the ratio exceeds a configurable threshold value, the GC raises an
OutOfMemoryError
... even though (technically) there is free memory available. This is probably what you are seeing, though the other explanations are equally plausible.You can change the GC thresholds, generation sizes, etc via JVM options, but it is probably better not to. A better idea is to figure out why your application's memory usage is continually creeping upwards. There are most likely memory leaks ... i.e. a bugs ... in your code that are causing this. Spend your effort finding and fixing those bugs, rather than worrying about why you are not using all of the memory.
(In fact, you are using it ... but not all of the time.)
Xmx/Xms
选项设置总体堆大小。因此,一个区域(具有默认大小)实际上是永久空间 - 也许,我们不知道有关压力测试的详细信息,实际上没有对象从伊甸园移动到永久或永久空间,因此当伊甸园耗尽时,这些区域仍然是空的的空间。The
Xmx/Xms
option sets the overall heap size. So a region (with a default size) is actually the Permanent Space - and maybe, we don't know details about your stress test, no objects are actually moved from eden to tenured or permanent, so those regions remain empty while Eden runs out of space.Java 将其内存分为几代。如果终身代已满,您可能会收到堆空间错误。通常,它们会动态调整大小,但如果您设置了固定大小,则不会。
Java splits its memory into generations. You can get a heap space error if the tenured generation fills. Normally, they resize dynamically but if you have set a fixed size it won't.