java.exe 进程使用了​​更多内存并且没有释放它

标签 java process garbage-collection heap-memory

我有一个 java 应用程序,在任何复杂执行之前处于空闲状态时,它在堆中使用 23 MB,而 TaskManager 中的 java.exe 进程大小约为 194 MB。经过一些复杂的操作,java.exe 的大小增长到 500MB 左右,堆大小也增长了。通过调用 System.gc() 方法进行几次完整 GC 后,堆大小减少回 23MB。但是 java.exe 的大小从大约 600MB 减少到大约 237MB,其中仍然有大约 43MB 的数据。有没有办法减少这个?还是因为某些行为?

最佳答案

这很正常,不用担心。 JVM 在需要执行一些复杂的逻辑时会获取内存。当 java 完成任务处理后,JVM 仍会将该内存保留为保留空间,不会释放回操作系统。这种架构有助于提高性能,因为 JMV 不必再次从底层操作系统请求相同的内存。它仍然在您在 -Xmx JVM 参数中定义的范围内。

有关一些有趣的详细信息,请参阅此 IBM 链接。 http://www-01.ibm.com/support/docview.wss?uid=swg21326774

不幸的是,这是 JVM 的灰色区域之一;您真的无法控制操作系统和 JVM 如何在彼此之间共享内存。将 JVM 视为需要一些内存才能运行的虚拟操作系统。您的父操作系统和 VM 都渴望资源,并希望尽可能多地保留已获得的资源。从操作系统请求更多内存是一项耗时的操作,因此 大多数 JVM 不会将内存释放回操作系统,即使它们不再需要它也是如此。

有关内部 JVM 内存管理的更多详细信息,请参阅 Oracle 的这份白皮书。 http://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf

我建议您先阅读 IBM 链接,然后再深入研究白皮书中解释的奇怪的内存世界。这两个链接都非常有用和有趣。

关于java.exe 进程使用了​​更多内存并且没有释放它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16649601/

相关文章:

java - 实现深度优先图遍历

objective-c - 如何获取 Mac 上所有正在运行的进程的列表?

java - JMH 基准迭代中的随机峰

Java -Xms 初始大小效果

java - 如何验证 JSoup 选择字符串

java - 如何将 javaScript 函数传递给 Java 方法以充当回调 (Rhino)

Bash 条件基于命令的退出代码

c - 为什么父进程只读取子进程的第一条和第六条消息?

objective-c - 双模 ARC/GC 和 Core Foundation 桥接

java - 如何让translate()方法接收字符串或与字符串类型兼容的给定列表?