[ZGC] [aarch64] Unable to allocate heap for certain Linux kernel configurations

Christoph Göttschkes christoph.goettschkes at microdoc.com
Fri Aug 28 08:40:40 UTC 2020


Hi,

I didn't file a bug yet, because I first wanted to get some feedback on 
this topic. Maybe this was a design choice and is not a bug.

On one of our test devices (a rock64 [1] running Debian GNU/Linux) I am 
unable to use ZGC due to the heap allocation scheme used by the JVM and 
the Linux kernel configuration for the device.

$ uname -a
Linux rock64-aarch64-1 4.4.190-1233-rockchip-ayufan-gd3f1be0ed310 #1 SMP 
Wed Aug 28 08:59:34 UTC 2019 aarch64 GNU/Linux
$ getconf PAGE_SIZE
4096
$ zcat /proc/config.gz |grep PGTABLE_LEVELS
CONFIG_PGTABLE_LEVELS=3

The problem is, the Linux kernel is configured to only use 3 pagetable 
levels, not 4. According to the kernel documentation [2], using 3 
pagetable levels and a page size of 4k, the highest virtual address 
available to userspace programs is 0x007f_ffff_ffff. If 4 pagetable 
levels are used with 4k pages, the address range is bigger and goes up 
to 0xffff_ffff_ffff for userspace programs.

Because of the memory allocation scheme used by ZGC [2], the JVM is not 
able to allocate the heap if ZGC is used on an aarch64 device, if the 
Linux kernel is configured to only use 3 pagetable levels with a page 
size of 4k. According to the documentation, the heap layout is only 
determined by the size of the Java heap, not by the capabilities of the 
device. On the rock64, which has 4GB of RAM, the JVM only tries to 
allocate the heap on addresses > 0x0400_0000_0000, which is well beyond 
the maximum address for userspace programs. Because of this, the JVM 
terminates during startup, because it is unable to allocate the heap, 
even though there are still more than 3 GB of RAM available.

$ free -m
          total   used   free  shared  buff/cache  available
Mem:      3986     56   3714      18         215       3880
Swap:        0      0      0

I understand that using 3 pagetable levels is not a very common case. In 
fact, on the rock64, the Linux kernel is very well capable of using 4 
pagetable levels. We have an Arch Linux ARM based installation, and in 
this distribution, the Linux kernel is configured to use 4 pagetable 
levels. This is the first time I encounter this, so chances are very 
high that none of our other aarch64 test devices are using 3 pagetable 
levels.

I am bringing this topic up, because I wasn't aware of this limitation 
and couldn't find a discussion or documentation about it. Was the design 
decision for using such high addresses made while being aware of this 
possible limitation? Might it be feasible to make an auto detect 
mechanism, for such cases? Or maybe lower the address range used for 
small heaps (maybe a heap below 8GB could use a different address 
range)? I don't really know if there are any aarch64 devices which are 
only capable of using 3 pagetable levels around and this is a real world 
problem or not. But this limitation should at least be documented, and 
maybe a command line option should be introduced for these very specific 
Linux kernel configurations.

-- Christoph

[1] https://www.pine64.org/devices/single-board-computers/rock64/
[2] 
https://hg.openjdk.java.net/jdk/jdk/file/3123bebd1eff/src/hotspot/cpu/aarch64/gc/z/zGlobals_aarch64.cpp




More information about the hotspot-gc-dev mailing list