Runtime.getRuntime().freeMemory() with ZGC

Per Liden per.liden at oracle.com
Fri May 28 15:13:45 UTC 2021


On 5/28/21 4:44 PM, Mike Rettig wrote:
>>> _capacity is the current heap size, not the max heap size. Maybe that's
>>> the reason why you see a lower than expected number?
> 
> That could be it. Does this value ever decrease over the life of the app if
> memory is never uncommitted?

Nope, only an uncommit event will lower capacity ("capacity" is the same 
as "committed memory").

> 
> Here are the command line memory settings. Soft heap isn't set so I think
> that means memory can't be uncommitted.
> 
> -XX:InitialHeapSize=12884901888 -XX:MaxHeapSize=32210157568
> -XX:MinHeapSize=12884901888

Memory will be uncommitted with this configuration, but only down to 
MinHeapSize and only memory that has been unused for ZUncommitDelay 
(which defaults to 300 seconds). So, if you application is filling up 
the heap regularly and no SoftMaxHeapSize is set, the likelihood of 
having some memory sit unused for 300s is low and nothing will be 
uncommitted. On the other hand, if your application were to idle for 
more than ZUncommitDelay, then unused memory would be uncommitted.

If you're looking to keep memory footprint down, then it's a good idea 
to configure SoftMaxHeapSize/MaxHeapSize to give your application 
headroom in case its memory requirements increase (semi-)temporarily, 
and then let ZGC uncommit that memory again when that (semi-)temporary 
need is gone.

But also note that uncommitting memory is expensive, so e.g. 
aggressively lowering ZUncommitDelay comes with a throughput and latency 
impact on your application.

/Per

> 
> [2021-05-27T16:01:23.976-0500] Safepoint "ZMarkStart", Time since last:
> 7258625285 ns, Reaching safepoint: 49579 ns, At safepoint: 46607 ns, Total:
> 96186 ns
> [2021-05-27T16:01:23.981-0500] Safepoint "ZMarkEnd", Time since last:
> 4386873 ns, Reaching safepoint: 35872 ns, At safepoint: 12460 ns, Total:
> 48332 ns
> [2021-05-27T16:01:23.999-0500] Safepoint "ZRelocateStart", Time since last:
> 18145829 ns, Reaching safepoint: 45824 ns, At safepoint: 9224 ns, Total:
> 55048 ns
> [2021-05-27T16:01:24.001-0500] GC(148) Garbage Collection (System.gc())
> 20840M(68%)->88M(0%)
> 
> The free heap is checked 2 seconds after the end of the GC.
> 
> 2021-05-27T16:01:26.116-05:00 FreeMemory 20750mb
> 
> 
> On Fri, May 28, 2021 at 2:00 AM Stefan Karlsson <stefan.karlsson at oracle.com>
> wrote:
> 
>>
>>
>> On 2021-05-27 23:24, Mike Rettig wrote:
>>> How is Runtime.getRuntime().freeMemory() implemented with ZGC? I am using
>>> that value to determine the available heap but it doesn't seem to be
>>> accurate with ZGC.
>>>
>>> For example, Runtime.freeMemory() says there are 20gb free, but looking
>> at
>>> the gc logs at the time, ZGC says there should be over 30gb available.
>>> Other times Runtime.freeMemory() reports less than 1mb free, but I know
>>> that isn't true from gc logs and app performance.
>>>
>>> Does Runtime.freeMemory() return something other than the available heap
>>> with ZGC?
>>
>> This is what ZGC reports:
>>
>> Java_java_lang_Runtime_freeMemory(JNIEnv *env, jobject this)
>> {
>>       return JVM_FreeMemory();
>> }
>>
>> ---
>>
>> JVM_ENTRY_NO_ENV(jlong, JVM_FreeMemory(void))
>>     size_t n = Universe::heap()->unused();
>>
>> ---
>>
>> size_t ZCollectedHeap::unused() const {
>>     return _heap.unused();
>> }
>>
>> ---
>>
>> size_t ZHeap::unused() const {
>>     return _page_allocator.unused();
>> }
>>
>> ---
>>
>> size_t ZPageAllocator::unused() const {
>>     const ssize_t capacity = (ssize_t)Atomic::load(&_capacity);
>>     const ssize_t used = (ssize_t)Atomic::load(&_used);
>>     const ssize_t claimed = (ssize_t)Atomic::load(&_claimed);
>>     const ssize_t unused = capacity - used - claimed;
>>     return unused > 0 ? (size_t)unused : 0;
>> }
>>
>> ---
>>
>> _capacity is the current heap size, not the max heap size. Maybe that's
>> the reason why you see a lower than expected number?
>>
>> _claimed is a temporary value used when we uncommit memory and are about
>> to decrement _capacity, but haven't yet.
>>
>> Do you have a GC log from the time you saw the 20G vs 30G discrepancy?
>>
>> StefanK
>>
>>>
>>> Thanks,
>>>
>>> Mike
>>
>>


More information about the zgc-dev mailing list