Java 堆大小未完全使用

发布于 2024-11-05 10:23:47 字数 326 浏览 3 评论 0原文

我目前正在使用 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.

enter image description here

Why are these remaining 20m, not used?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

终弃我 2024-11-12 10:23:47

您需要了解有关垃圾收集器人体工程学的一个核心事实:

垃圾收集成本高昂的部分是查找和处理不是垃圾的对象。

这意味着:当堆接近其最大容量时,GC将花费越来越多的时间,而回收的空间回报却越来越少。如果 GC 尝试使用内存的最后一个字节,最终结果将是您的 JVM 将花费越来越多的时间进行垃圾收集,直到……最终……几乎没有完成任何有用的工作。

为了避免这种病态情况,JVM 会监视 GC 和执行有用工作所花费的时间比率。当该比率超过可配置的阈值时,GC 会引发 OutOfMemoryError ...即使(技术上)有可用的空闲内存。这可能就是您所看到的,尽管其他解释同样合理。

您可以通过 JVM 选项更改 GC 阈值、生成大小等,但最好不要这样做。更好的想法是找出应用程序的内存使用量不断上升的原因。您的代码中很可能存在内存泄漏...即错误...导致了这种情况。花精力查找并修复这些错误,而不是担心为什么没有使用所有内存。

(事实上​​,你正在使用它......但并非一直如此。)

You need to understand a central fact about garbage collector ergonomics:

The costly part of garbage collection is finding and dealing with the objects that are NOT garbage.

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.)

忘东忘西忘不掉你 2024-11-12 10:23:47

堆被划分为年轻代(伊甸园空间,以及两个大小相同的幸存者空间,通常称为From和To),老年代(Tenured)和永久空间。

Xmx/Xms 选项设置总体堆大小。因此,一个区域(具有默认大小)实际上是永久空间 - 也许,我们不知道有关压力测试的详细信息,实际上没有对象从伊甸园移动到永久或永久空间,因此当伊甸园耗尽时,这些区域仍然是空的的空间。

The heap is split up in Young-Generation (Eden-Space, and two Survivor-Spaces of identical size usually called From and To), Old Generation (Tenured) and Permanent Space.

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.

原来是傀儡 2024-11-12 10:23:47

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文