gpt4 book ai didi

Java JAR 内存使用 VS 类文件内存使用

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:54:29 25 4
gpt4 key购买 nike

我最近将我的大型 Java 应用程序更改为以 JAR 而非单个类文件的形式交付。我有 405 个 JARS,其中包含 5000 个类文件。我的问题是,当我将程序作为 JAR 运行时(类路径是获取所有 JAR 的通配符),Java 将不断使用越来越多的内存。我已经看到内存超过 2GB,而且 Java 似乎没有执行停止世界的垃圾收集来降低内存。如果我针对展开的 JAR(仅类文件)运行完全相同的程序,Java 的内存使用率会低得多(< 256MB)并保持在那里。这发生在 Windows 7 (x64) 和 Windows Server (x64) 上的 Oracle Java 8 中。为什么将我的应用程序打包为 JAR 会更改内存配置文件?此外,我已经将程序作为 JAR 运行了很长时间,最大内存限制为 128MB,没有任何问题,所以我没有内存泄漏。

类路径中的 JAR 文件 With JAR files in classpath

类路径中的类文件 With class files in classpath

编辑:我接受了@K Erlandsson 的回答,因为我认为这是最好的解释,而这只是 Java 的一个丑陋的怪癖。感谢大家(尤其是@K Erlandsson)的帮助。

最佳答案

首先要注意的是,堆上完全使用了多少内存在任何时候都不是很有趣,因为使用的大部分内存可能是垃圾,将被下一次 GC 清除。

您需要关注的是 Activity 对象使用了多少堆。您在评论中写道:

I don't know if this matters, but if I use jvisualvm.exe to force a GC (mark sweep) the heap memory usage will drop clearing almost all the heap memory.

这很重要。 很多。这意味着当您在使用 jar 时看到更高的堆使用率时,您会看到更多的垃圾,而不是 Activity 对象消耗的更多内存。当您执行 GC 时垃圾被清除,一切都很好。

从 jar 文件加载类比从类文件加载它们暂时会消耗更多的内存。需要打开、查找和读取 jar 文件。与简单地打开特定的 .class 文件并读取它相比,这需要更多的操作和更多的临时数据。

由于大部分堆使用都被 GC 清除,因此您不需要非常关注这种额外的内存消耗。

你还写:

Java will continually use more and more memory. I have seen the memory go > 2GB and it seems like Java is not doing stop-the-world garbage collections to keep the memory lower.

这是典型的行为。 GC 仅在 JVM 认为有必要时运行。 JVM 将根据内存行为对此进行调整。

编辑:现在我们看到了您的 jConsole 图像,我们看到了提交堆内存的不同(250 MB 与 680 MB)。提交堆是堆的实际大小。这将有所不同(取决于您使用 -Xmx 设置的值),具体取决于 JVM 认为将为您的应用程序产生最佳性能的内容。但是,它主要会增加,几乎不会减少。

对于 jar 情况,JVM 已为您的应用程序分配了更大的堆。可能是由于在初始类加载期间需要更多内存。 JVM 然后认为更大的堆会更快。

当您拥有更大的堆、更多的提交内存时,在运行 GC 之前有更多的内存可供使用。这就是为什么您会看到两种情况下内存使用情况的差异。

底线:您看到的所有额外使用都是垃圾,而不是 Activity 对象,为什么您不需要担心这种行为,除非您有实际问题,因为内存将在下一次 GC。

关于Java JAR 内存使用 VS 类文件内存使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31079320/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com