DirectMemory容量可通过-XX:MaxDirectMemorySize指定,如果不指定,则默认与Java堆的最大值(-Xmx指定)一样。代码中越过了DirectByteBuffer类,直接通过反射获取Unsafe实例并进行内存分配(Unsafe类的getUnsafe()方法限制了只有引导类加载器才会返回实例,也就是设计者希望只有rt.jar中的类才能使用Unsafe的功能)。因为,虽然使用DirectByteBuffer分配内存也会抛出内存溢出异常,但它抛出异常时并没有真正向操作系统申请分配内存,而是通过计算得知内存无法分配,于是手动抛出异常,真正申请分配内存的方法是unsafe.allocateMemory()。
代码如下:
package oom; import java.lang.reflect.Field; import sun.misc.Unsafe; /** * 本机直接内存溢出 * @author Madison * @date 2014-7-12 * VM Args:-Xmx20M -XX:MaxDirectMemorySize=10M */ public class DirectMemoryOOM { private static final int _1MB = 1024 * 1024; public static void main(String[] args) throws Exception { 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
at sun.misc.Unsafe.allocateMemory(Native Method)
at oom.DirectMemoryOOM.main(DirectMemoryOOM.java:22)
欲知后事如何,且听下回分解
本文出自 “2377209” 博客,转载请与作者联系!
JVM【第九回】:【OutOfMemoryError异常之本机直接内存溢出】,布布扣,bubuko.com
JVM【第九回】:【OutOfMemoryError异常之本机直接内存溢出】
原文:http://2387209.blog.51cto.com/2377209/1531204