Reputation: 73
I got two conflicting answers regarding this question from two places.
For example, Parallel GC doesn’t release unused memory back to the OS readily.
So I think Parallel GC will not shrink the heap size.
you can make the GC more aggressive in general by setting -XX:GCTimeRatio=19 -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=30 which will allow it to spend more CPU time on collecting and constrain the amount of allocated-but-unused heap memory after a GC cycle.
So I think I can force the garbage collector to shrink the heap size.
Based on the above understanding, I do experiments on my machine.
3.1 The jdk:
java version "1.8.0_271"
Java(TM) SE Runtime Environment (build 1.8.0_271-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.271-b09, mixed mode)
3.2 I use jmap -heap
command to print the GC information, the output is as below
.....(omit other infomration)
using thread-local object allocation.
Parallel GC with 8 thread(s)
3.3 I run an application with VM options -Xmx10240m
(it is the only heap-related VM option I set manually), and open jvisualvm
to observe the change of heap size. I notice the heap size(the orange part) shrinks when the used heap size(the blue part) becomes smaller. It violates the first article.
3.4 I run the same application with VM options -Xmx10240m -XX: MaxHeapFreeRatio=100
, I set the option -XX:MaxHeapFreeRatio=100
in order to tell GC not to shrink. But it does not work either.
My concrete question is:
4.1 The baeldung article says Parallel GC doesn’t release unused memory, so why does the heap size in Figure 1 still shrink?
4.2 The so thread says the -XX:MaxHeapFreeRatio will make some differences, but it didn't.
Any help will be appraciated.
Upvotes: 0
Views: 528
Reputation: 21630
I think you misread the baeldung article.
The article Does GC Release Back Memory to OS? writes
For example, Parallel GC doesn’t release unused memory back to the OS readily.
You marked the first part but missed the last word: readily. That sentence is
For example, Parallel GC doesn’t release unused memory [..] readily.
i.e. it can release memory back to the OS, but it is reluctant to do so (probably because releasing memory back to the OS just to allocate new memory from the OS is expensive).
The so thread says the -XX:MaxHeapFreeRatio will make some differences, but it didn't.
Yes it says so. And it writes that you can make the GC more aggresive by setting (among others) -XX:MaxHeapFreeRatio=30
.
The point is: the default value for MaxHeapFreeRatio is 70. If setting it to 30 makes it more aggressive, then setting it to 100 makes it less aggressive.
You can actually see in PSAdaptiveSizePolicy::calculated_old_free_size_in_bytes()
that setting the MaxHeapFreeRation to 100 effectively disables it.
Upvotes: -1
Reputation: 298489
In this bug report about releasing memory, there is a ten year old comment from Jesper Wilhelmsson:
I have verified that G1 (-XX:+UseG1GC), Parallel scavenge (-XX:+UseParallelGC) and ParallelOld (-XX:+UseParallelOldGC) do return memory when the heap shrinks. I'm not so sure about Serial and CMS, they didn't shrink their heap in my experiments.
Both parallel collectors do require a number of GCs before shrinking the heap down to an "acceptable" size. This is per design. They are deliberately holding on to the heap assuming that it will be needed in the future. Setting the flag -XX:GCTimeRatio=1 will improve the situation somewhat but it will still take several GCs to shrink a lot.
I would trust the JDK developers more than articles on baeldung.com or rather, I’d treat articles on baeldung.com with a grain of salt in general. There is no sign of a quality assurance process on that site and it’s not the first time, incorrect information has been found on that site.
Upvotes: 1