Force JVM to free memory
我改进了代码以从垃圾收集器中获得更好的结果。
现在,当我调用
这是否意味着我的改进正在发挥作用,并且我的所有引用都正确,我可以忽略 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
未使用的内存是浪费的内存。
为什么要显式调用
通常是一种不好的做法
你可以在 Java 中出现内存泄漏,但这肯定不是你的情况要考虑的事情,因为正如你在调用
为什么您认为您的代码有问题?可能不需要更多内存,或者如果需要内存,你已经有足够的内存了(用外行的话来说,GC 不会释放内存,因为程序还有很多东西可以运行 -那么GC为什么要清理内存呢?)。
当然,您有可能存在内存泄漏,这意味着您的程序一直在分配内存而从未释放它。 (例如,在不断增长的列表或地图中。)您将需要一个内存分析器来确保您不会遇到这种情况。
除此之外,如果虚拟机似乎一直在分配内存而不释放它,我不会担心。这就是现代 VM 的工作方式,尤其是在"客户端"模式下:只要有足够的可用内存,它们就不会浪费时间进行垃圾收集。如果接近内存限制,那么垃圾收集器就会启动。 ("客户端"与"服务器"模式是一个 JVM 参数,如果需要,您可以尝试使用它,更多信息在这里:"java -server"和"java -client"之间的真正区别?)
除此之外,你可以做的是:
a) 确保执行完整 GC 的机制实际上是执行完整 GC。我所知道的最好的机制(不能保证有效,但据我所知它似乎有效)是分配一个仅通过软引用引用的对象,然后继续调用 GC 直到软引用变为 null .
b) 在调试运行时(例如,如果启用了断言),每隔几秒就会在单独的线程上触发一次完整的 GC。然后,如果您查看 VM 消耗的内存,它应该大致保持不变。如果没有,你有内存泄漏。
没有办法强制JVM释放内存,
JVM 在启动时保留内存并向操作系统请求额外的内存,直到达到配置的任何限制。它以块增量的方式执行此操作,一次请求 MB 或更多内存,因为从 OS 逐字节请求内存效率非常低。