实验代码
/**
* VM Args:-XX:MaxDirectMemorySize=512m
*/
public class GCTest {
private static final int _1GB=1024*1024*1024;
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
Field unsafeField = Unsafe.class.getDeclaredFields()[0];
unsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe)unsafeField.get(null);
int num=0;
while(true){
num++;
unsafe.allocateMemory(_1GB);
System.out.println(num);
}
}
}
实验结果1: 直接内存不在非堆空间的计算之列
下图可见,当在直接内存中分配了4G的空间之后,jconsole反映的堆外内存仍然只有之前的15m,可见直接内存不在非堆空间的计算之列,而且已有的所有jdk工具都无法去观测到直接内存的大小,理由可想而知:因为这块区域并不是虚拟机管理的内存
实验结果2: 无法去限制直接内存的大小
2.1 -XX:MaxDirectMemorySize 该参数亲测无效 (本机环境jdk1.8)
尽管我设置了:-XX:MaxDirectMemorySize=512m 但仍然是在机器的内存用尽之后才报内存溢出,实验是循环了40次,在分配了40GB的空间(用尽了本机子的所有内存)后报OOM异常
所以整个直接内存这块区域是这样的:初始大小为0,你申请多少就分配多少,直至机器的内存耗尽