# Background:
ZGC uses three different types of memory regions (Small, Medium and Large) as a compromise between memory waste and relocation induced latencies.
The allocated object size dictates which type of memory region it ends up in. These sizes are selected such that when an object allocation fails in a memory region because that object does not fit, the waste (unused bytes at the end) is at most 1/8th or 12.5%. This property is held for both the small and medium memory regions.
Objects larger than medium object allocation gets placed in a large memory region, which only ever contains one object. And because all memory region sizes are multiples of 2M, we end up with a memory waste which is the difference between object size rounded up to the nearest multiple of 2M and the exact object size.
For max heaps (Xmx) smaller than 1GB we use reduced medium memory region sizes at the cost of worse waste guarantees for large object allocation.
But for max heaps 1GB or larger our current selected medium memory region size is 32M. This results in a max medium object size of 4M (32M * 12.5%), which is the max size we want an application thread to have to relocate. So we end up with a guarantee that the waste in large memory regions is at most 33%.
A problem with medium pages is that they may cause allocation induced latencies. To reduce allocation latencies we track (cache) memory of memory regions which has been freed by the GC, so it can be reused for new memory regions used for allocations.
For small memory regions, as long as there is cached memory, it can use it, because the size of a small memory region (2M) is always a multiple of any other memory region that has been freed.
However for medium memory regions it may be that there is enough memory available in the cache, but it is only split into regions smaller than the medium memory regions size (32M). Currently this requires the allocating thread to remap multiple of these small memory regions into a new larger one, which involves calls into the operating system.
In ZGC we call our memory regions pages or zpages.
# Proposal:
First allow for medium pages to have multiple sizes. Specifically allow all power of two sizes between the smallest size that can contain one medium object and the max medium page size. For a max medium page size of 32M the sizes ends up being {4M, 8M, 16M, 32M}.
Second add a "fast" medium page allocation path in the page allocator, which only claims memory from the cache, where the memory can directly satisfy one of these sizes. This will only fail if the cache is empty, or if all the memory is spread out in 2M segments. Then use this in the object allocator for when mutator threads allocate or relocate objects. Reducing the probability that allocation or mutator relocation sees latencies induced by the page allocation.
The plan is to have GC relocation workers still allocate only the largest medium page size, and having the GC take the cost remapping memory. This way we can reduce mutator latencies at the cost of potential temporary increased memory waste.
The change from a fixed to variable size for medium pages requires some adaptation in relocation set selection.
ZGC uses three different types of memory regions (Small, Medium and Large) as a compromise between memory waste and relocation induced latencies.
The allocated object size dictates which type of memory region it ends up in. These sizes are selected such that when an object allocation fails in a memory region because that object does not fit, the waste (unused bytes at the end) is at most 1/8th or 12.5%. This property is held for both the small and medium memory regions.
Objects larger than medium object allocation gets placed in a large memory region, which only ever contains one object. And because all memory region sizes are multiples of 2M, we end up with a memory waste which is the difference between object size rounded up to the nearest multiple of 2M and the exact object size.
For max heaps (Xmx) smaller than 1GB we use reduced medium memory region sizes at the cost of worse waste guarantees for large object allocation.
But for max heaps 1GB or larger our current selected medium memory region size is 32M. This results in a max medium object size of 4M (32M * 12.5%), which is the max size we want an application thread to have to relocate. So we end up with a guarantee that the waste in large memory regions is at most 33%.
A problem with medium pages is that they may cause allocation induced latencies. To reduce allocation latencies we track (cache) memory of memory regions which has been freed by the GC, so it can be reused for new memory regions used for allocations.
For small memory regions, as long as there is cached memory, it can use it, because the size of a small memory region (2M) is always a multiple of any other memory region that has been freed.
However for medium memory regions it may be that there is enough memory available in the cache, but it is only split into regions smaller than the medium memory regions size (32M). Currently this requires the allocating thread to remap multiple of these small memory regions into a new larger one, which involves calls into the operating system.
In ZGC we call our memory regions pages or zpages.
# Proposal:
First allow for medium pages to have multiple sizes. Specifically allow all power of two sizes between the smallest size that can contain one medium object and the max medium page size. For a max medium page size of 32M the sizes ends up being {4M, 8M, 16M, 32M}.
Second add a "fast" medium page allocation path in the page allocator, which only claims memory from the cache, where the memory can directly satisfy one of these sizes. This will only fail if the cache is empty, or if all the memory is spread out in 2M segments. Then use this in the object allocator for when mutator threads allocate or relocate objects. Reducing the probability that allocation or mutator relocation sees latencies induced by the page allocation.
The plan is to have GC relocation workers still allocate only the largest medium page size, and having the GC take the cost remapping memory. This way we can reduce mutator latencies at the cost of potential temporary increased memory waste.
The change from a fixed to variable size for medium pages requires some adaptation in relocation set selection.
- links to
-
Commit(master) openjdk/jdk/f74fbfe5
-
Review(master) openjdk/jdk/25381