Runtime.getRuntime().freeMemory() with ZGC

Mike Rettig mike.rettig at gmail.com
Fri May 28 14:44:43 UTC 2021


>>_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?

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

[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