Specify Java Memory Allocation Pool Address

With the -Xms and -Xmx you can set the initial and maximum size of the memory allocation pool. Using strace / truss on Linux and AIX, I found that the JVM internally uses the (k) mmap system call. The parameter address is NULL, so the operating system decides on which virtual memory address it maps the memory.

 $ truss java -Xmx512M Hello 2>&1 | grep mmap kmmap(0x00000000, 536870912, 3, 17, -1, 0x00000000, 0x00000000) = 0xB0000000 

Can this address be specified?

Reference Information. I need to call outdated code through the Java Native Interface (JNI), which requires a huge amount of non-moving data (2 GB in 32-bit address space) displayed in a specific place in memory. This area overlaps with the location of the Javas memory allocation pool.

Edit: this is the actual memory layout:

 0x0... AIX 0x1... Text 0x2... Stack 0x3... Heap 0x4... Heap ...... Legacy Data (2 GB) 0xd... Shared Library Text 0xe... unused 0xf... Shared Library Data 

My goal is to move the Java memory allocation pool from 0xb / 0xc to the 0x3 / 0x4 segments, which is also available in the standard (not large) memory model.

+4
source share
3 answers

Perhaps you could turn this problem inside out. Start your own process and do what you need to do to reserve your non-negotiable space (mmap or something else). Then use the Java call API to create and run the JVM inside your own process. I cannot find any documentation on how the JVM manages its memory, but it is reasonable that it will play well with the memory that has already been allocated by the host process (I would assume that it just uses the local malloc), so it will find somewhere else a bunch. If you leave the 0x3-0x4 region unallocated, you can hope that it will put it there.

However, I think there is a real risk that your memory model does not have enough address space for the JVM. Area 0x3-0x4 - is that 512 MB? If you can host the whole JVM (heap, stack, perm, VM structures, etc.) there, then fine, but if not, you may find that when the JVM cannot allocate contiguous memory for the heap, it is very upset. Or it is not. I really do not know.

So, having proposed this, I strongly recommend that you not do this, but instead follow the sleske tips and put your own code in a separate process.

+2
source

Personally, I have never heard of a way to configure the distribution pool address. If there is such a setting, it is probably very obscure.

The only way to make sure that you look at the JDK / JRE source, available at http://hg.openjdk.java.net/ . If the NULL parameter NULL hard-coded, you're out of luck.

For an alternative solution, if you cannot fix the incorrect native code:

You can write a small native program to call your own code, and then call the program from Java (via Runtime.exec ). Thus, naughty code gets its own OS process with a separate address space. Of course, this is only possible if there is not too much back-and-forth between native code and Java.

Or make code on a small server that runs in parallel with your Java application, so they can communicate ...

Note:

I just noticed in the manpage mmap that specifying the mmap address is not necessarily supported:

MAP_FIXED: Interpret addr exactly. [...] An implementation is defined, regardless of whether MAP_FIXED should be supported. MAP_FIXED must be supported by XSI-compatible systems. [...] When MAP_FIXED is not set, the implementation uses addr in the implementation-defined come to pa.

http://linux.die.net/man/3/mmap

Thus, even if you manage to call the mmap JVM call with a specific address, this may still not work.

+2
source

One idea you can try is to use LD_PRELOAD to enter your own kmmap behavior. Google provides an example LD_PRELOAD for entering custom malloc in a TCMalloc project.

+1
source

Source: https://habr.com/ru/post/1334079/


All Articles