DirectMemory容量可通過-XX:MaxDirectMemorySize指定,如果不指定,則默認與JAVA堆的最大值(-Xmx指定)一樣。
以下代碼越過了DirectByteBuffer類,直接通過反射獲取Unsafe實例並進行內存分配(Unsafe類的getUnsafe()方法限制類只有引導類加載器才會返回實例,也就是設計者希望只有rt.jar中的類才能使用Unsafe的功能)。因為,雖然使用DirectByteBuffer分配內存也會拋出內存溢出異常,但它拋出異常時並沒有真正向操作系統申請分配內存,而是通過計算得知內存無法分配,於是手動拋出異常,真正申請分配內存的方式是unsafe.allocateMemory().
/**
* VM args : -Xms20M -XX:MaxDirectMemorySize=10M
*
*/
public class DirectMemoryOOM {
private static final int _1MB = 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);
while(true){
unsafe.allocateMemory(_1MB);
}
}
}
運行結果 :Exception in thread "main" java.lang.OutOfMemoryError