繁体   English   中英

强制JVM释放内存

[英]Force JVM to free memory

我改进了我的代码,以便从垃圾收集器中获得更好的结果。

现在,当我调用System.gc()它释放所有内存。 但是当我在不调用System.gc()的情况下观察内存使用情况时,应用程序会保留并使用越来越多的内存。

这是否意味着我的改进正在发挥作用,我的所有引用都是正确的,我可以忽略JVM如何自行释放内存。 或者我的代码中是否存在另一个问题,即JVM在不运行垃圾收集器的情况下保留更多内存的原因。

取决于您的JVM使用哪个GC。 如果它是JDK9那么它可能是G1,它在内存消耗方面是“贪婪”的,所以根据你检查内存使用的方式,它看起来好像占用了大量的内存(在这里保留它并动态/按需使用/释放。

您可以使用

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

检查内存消耗。

至于GC和内存消耗分析,请查看以下内容: G1垃圾收集器的高内存使用问题 + https://www.javacodegeeks.com/2017/11/minimize-java-memory-usage-right-garbage-collector.html

未使用的内存浪费了内存。

为什么要显式调用System.gc() 恕我直言,你永远不应该调用它并将其留给JVM来决定何时运行GC。 (如果你是新手JVM可以比你更好的决策。调用System.gc() ,只有当你真的知道自己在做什么。)这通常是一个不好的做法来调用System.gc()

System.gc()只是JVM运行GC的请求/提示。 它绝不意味着GC肯定会运行。

您可以在Java中使用内存泄漏,但这肯定不是您在案例中要查看的内容,因为正如您在调用System.gc()时提到的那样,您可以看到一些内存被释放。 (因此,您仍然不能保留未使用对象的引用,这可能会阻止GC清理这些对象。)

为什么你认为这是你的代码的问题? 可能的情况是不需要进一步的内存或者需要内存,你已经有足够的内存(并且以外行的话说,GC不会释放内存,因为程序运行还有很多 - 那么GC为什么要打扰内存?)

没有办法强制JVM释放内存, System.gc()只是一个提示。 由GC来管理内存(注意有各种类型的内存,例如堆,元空间,堆外)。 每个GC算法都有多个配置参数可供您调整,但两者都不会为您提供按需释放内存的选项。

JVM在启动时保留内存,并从操作系统请求额外的内存,直到达到配置的任何限制。 它以块增量执行,一次请求MB或更多内存,因为从字节逐字节地请求内存将是非常低效的。

当然有可能存在内存泄漏,这意味着您的程序在不释放内存的情况下不断分配内存。 (例如,在不断增长的列表或地图中。)您将需要一个内存分析器,以确保您没有遭受这种情况。

除此之外,我不担心虚拟机是否会在不释放内存的情况下继续分配内存。 这就是现代虚拟机的工作方式,特别是在“客户端”模式下:只要有足够的可用内存,它们就不会浪费时间进行垃圾收集。 如果接近内存限制,那就是垃圾收集器启动的时间。 (“客户端”与“服务器”模式是一个JVM参数,如果需要,可以试用它,更多信息: “java -server”和“java -client”之间的真正区别?

除此之外,你可以做的是:

a)确保执行完整GC的机制实际上是执行完整的GC。 我所知道的最好的机制(不能保证工作,但它似乎可以工作)就是分配一个仅通过软引用引用的对象,然后继续调用GC直到软引用变为null 。

b)在调试运行时(例如,如果启用了断言),每隔几秒就在一个单独的线程上继续触发一个完整的GC。 然后,如果你查看VM消耗的内存,它应该保持大致不变。 如果没有,你有内存泄漏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM