当垃圾收集器运行并释放内存时,该内存将返回操作系统,还是作为进程的一部分保留。我印象深刻的是,该内存实际上从未释放回OS,而是保留为内存区域/池的一部分,以供同一html" target="_blank">进程重用。
结果,进程的实际内存将永远不会减少。一篇使我想起的文章是Java的Runtime是用C / C ++编写的,所以我想同样的事情适用吗?
更新
我的问题是关于Java的。我之所以提到C / C ++,是因为我假设Java的分配/取消分配是由JRE使用某种形式的malloc / delete完成的
在热点JVM不释放内存给操作系统,但不会因为调整堆所以勉强是昂贵的,它假定,如果你需要的堆一旦你会再次使用它。
你可以通过设置使其更具侵略性,-XX:GCTimeRatio=19 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=30
从而使其在GC周期后花费更多的CPU时间来收集和限制已分配但未使用的堆内存量。
假设你正在使用并发收集器,还可以将-XX:InitiatingHeapOccupancyPercent=NN
设置为一个较低的值,以使GC几乎连续运行并发收集,这将消耗更多的CPU周期,但会更快地缩小堆。通常这不是一个好主意,但是在某些类型的具有大量备用CPU内核但内存不足的机器上,这是有道理的。
如果你使用的收集器具有默认的暂停时间目标(CMS或G1),则你也可以放宽该目标,以在收集器上设置更少的约束,或者你可以切换并行收集器,以在暂停时间之前优先考虑占用空间。
此外,通过Java 9 -XX:-ShrinkHeapInSteps
选项,可以更积极地应用由前两个选项引起的缩小。相关的OpenJDK错误。
请注意,收缩能力和行为取决于所选择的垃圾收集器。例如,G1仅使用jdk8u20 获得了在堆中间退回未使用的块的能力,而ZGC 使用jdk13进行了回收,而ε收集器则极有可能不会这样做。
因此,如果需要堆收缩,则应该针对特定的JVM版本和GC配置进行测试。
GC Logging with PrintAdaptiveSizePolicy
也可能提供洞察力,例如,当JVM尝试为年轻一代使用更多内存以满足某些目标时。
OpenJDK 12中还包含JEP 346,该JEP引入了带有G1PeriodicGCInterval
选件的G1GC的即时内存释放,但又以一些额外的CPU为代价。它还提到了Shenandoah和OpenJ9 VM中的类似功能。
当垃圾收集器运行并释放内存时,内存会返回操作系统还是作为进程的一部分保留下来。我的强烈印象是,内存实际上从未释放回操作系统,而是作为内存区域/池的一部分保留下来,供同一进程重复使用。 因此,进程的实际内存永远不会减少。提醒我的一篇文章是这样的,Java的运行时是用C/C写的,所以我想同样的事情也适用? 更新< br >我的问题是关于Java的。我提到C/C是因为我假设Java的分配/释放是由JRE
问题内容: 在Java运行时中,如果我的应用程序释放了内存,运行时是否将内存释放回OS?还是回到我的过程? 问题答案: 这取决于JVM的实现,在规范中未指定。 作为第一步,Sun JVM将保留它。一旦未使用一定比例(可配置)的已分配内存,它将将其中一部分返回给OS(行为受和设置影响)。
在阅读了一些像这样的答案和JEP-346之后,我意识到G1确实会将内存释放回操作系统。 然而,它是否将内存释放回操作系统,即使当前内存使用可能低于初始堆内存(即在此JEP之前,在我的案例中为JDK11)? 假设我有一个Java11 VM,运行和设置为,在RAM上,但是我只消耗大约。G1会释放足够的内存回操作系统吗? 我在任何地方都没有找到任何文档说明G1仅限于在发布时考虑Xms阈值。 我在生产过程
我正在为我的应用程序使用GC选项。 由于大多数人都已经体验过JVM擅长将堆增加到最大堆大小,但它不会将内存释放回操作系统。我遇到了
wcsdup等函数隐式调用malloc为目标缓冲区分配内存。我想知道,由于内存分配不是很明确,所以显式释放存储似乎合乎逻辑吗?这更像是一种设计困境,赞成和反对的理由如下 应释放,因为 不释放它会导致内存泄漏。 wcsdup/_wcsdup调用malloc来分配内存,即使是从C程序调用的。 不应该被释放,因为 wcsdup积累的内存最终会在程序退出时被释放。在整个程序生命周期中,我们总是会遇到一些内