即使Xms = Xmx,G1GC也会向操作系统释放内存吗? [英] Does G1GC release back memory to the OS even if Xms = Xmx?
问题描述
在阅读了 this 和
After reading some answers like this and JEP-346, I have realised that the G1 does release memory back to the OS.
但是它会将内存释放回操作系统,甚至到当前内存使用可能降到初始堆内存以下(即,在此JEP之前,对于我而言为JDK11)吗?
However does it release memory back to the OS, even to the point that current memory use can drop below the initial heap memory (i.e before this JEP, in my case JDK11)?
假设我在8GB
RAM上有一个运行Xms
并且Xmx
设置为5GB
的Java 11 VM,但是我只在1GB
上使用. G1会释放足够的内存回操作系统吗?
Assume I have a Java 11 VM running with Xms
and Xmx
set as 5GB
, on a 8GB
RAM, however I am consuming only around 1GB
. Will G1 release enough memory back to the OS?
我在任何地方都找不到任何文档,说G1被限制在发布时要牢记Xms
阈值.
I didn't find any documentation anywhere which says that the G1 is restricted to releasing keeping the Xms
threshold in mind.
我在生产中观察到此情况,MemAvailable一直下降到一个点,然后在GC之后,它在8GB的盒子上跳升到接近30-35%.因此,我假设它正在释放内存,这就是MemAvailable正在回跳的原因.
I am observing this in Production, the MemAvailable keeps on decreasing till a point, and then after a GC, it jumps upto close to 30-35% on an 8GB box. So I am assuming it is releasing memory, which is why the MemAvailable is jumping back up.
将内存释放到OS到底是什么意思,它是在调用free/unmap吗?
Also what does it exactly mean to release memory to the OS, is it calling free/unmap ?
推荐答案
注意:我已经删除了先前的答案并研究了源(也建立了自己的JVM
只是为了找出这一特定时刻),这是答案.
Note: I have deleted my previous answer and have studied the sources (also build my own JVM
just to find out this particular moment), here is the answer.
简短答案
JVM 11 version
(目前),使堆变小时,不会会低于Xms
.
JVM 11 version
(at the moment), will not go below Xms
when making the heap smaller.
详细答案
绝对真理在源代码中.并且此处是决定是否缩小堆的决定.在下面的几行中,您可以看到,如果我们输入if
,将出现一条日志语句:
The absolute truth is in the source code. And here is the decision taken to shrink the heap or not. A few lines below, you can see that if we enter that if
, there will be a log statement:
尝试堆收缩(容量大于完全GC后的最大所需容量).
Attempt heap shrinking (capacity higher than max desired capacity after Full GC).
因此,从本质上讲,如果我们可以理解两个参数:capacity_after_gc
和maximum_desired_capacity
-我们可以解决这个难题.通常,capacity_after_gc
并不容易掌握;主要是因为这取决于有多少垃圾以及当前GC可以回收多少垃圾.为简单起见,我将编写一些不会产生任何垃圾的代码,以便使该值恒定.
So in essence, if we can understand two parameters : capacity_after_gc
and maximum_desired_capacity
- we can solve this mystery. In general, capacity_after_gc
is not something easy to grasp; mainly because it depends on how much garbage there was and how much the current GC could reclaim. For simplicity, I am going to write some code that does not generated any garbage, so that this value is constant.
在这种情况下,我们只需要了解maximum_desired_capacity
.
In such a case, we only need to understand maximum_desired_capacity
.
在上面的几行中,您可以看到这是通过以下方式计算的:
A few lines above, you can see that this is computed as :
maximum_desired_capacity = MAX2(maximum_desired_capacity, min_heap_size);
不幸的是,这很棘手,因为要真正了解这些人机工程学是如何设置的,需要遵循并理解很多代码.尤其是因为它们取决于JVM
开头的各种参数.
Unfortunately, this is where it gets tricky, because it's a lot of code to follow and understand to really see how these ergonomics are set; especially since they depend on various arguments that the JVM
has been started with.