使用-Xms和-Xmx选项,可以设置内存分配池的初始和最大大小.在Linux和AIX上使用strace / truss我发现,JVM内部使用(k)mmap系统调用. address-Parameter为NULL,因此操作系统决定它映射内存的虚拟内存地址.
$truss java -Xmx512M Hello 2>&1 | grep mmap
kmmap(0x00000000, 536870912, 3, 17, -1, 0x00000000, 0x00000000) = 0xB0000000
有可能,指定这个地址吗?
背景:我必须通过Java Native Interface(JNI)调用遗留代码,这需要在内存中的特定位置映射大量不可重定位的数据(32位地址空间中的2 GB).该区域与Javas内存分配池的位置重叠.
编辑:这是实际的内存布局:
0x0... AIX
0x1... Text
0x2... Stack
0x3... Heap
0x4... Heap
...... Legacy Data (2 GB)
0xd... Shared Library Text
0xe... unused
0xf... Shared Library Data
我的目标是将Java内存分配池从0xb / 0xc移动到0x3 / 0x4段,这也可以在标准(非大型)内存模型中使用.
解决方法:
也许你可以从内到外解决这个问题.启动本机进程,并执行您需要做的事情来保留您的不可协商空间(mmap或其他).然后使用Java的invocation API在本机进程中创建和启动JVM.我找不到任何关于JVM如何进行内存管理的文档,但是it stands to reason它将与主机进程已分配的内存很好地配合(我猜它只使用本地malloc),所以它会找到放在其他地方.如果你保留0x3-0x4区域未分配,你可以希望它将它放在那里.
但是,我认为存在一个真正的风险,即JVM的内存模型中没有足够的地址空间. 0x3-0x4区域是什么,512 MB?如果你可以在那里安装一个完整的JVM(堆,堆栈,烫发,VM结构等),那么很好,但如果没有,你可能会发现当JVM无法为堆分配连续的内存时,它会非常沮丧.或者它可能不会.我真的不知道.
因此,建议这样做,我强烈建议您不要这样做,而是按照sleske’s advice并将本机代码放在一个单独的过程中.