Runtime.getRuntime().freeMemory() with ZGC

Stefan Karlsson stefan.karlsson at oracle.com
Fri May 28 06:59:54 UTC 2021


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