【JVM.1】java内存区域与内存溢出
2018-04-19 11:23
453 查看
鲁迅曾说过:Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进来,墙里面的人想出去。
一.虚拟机内存分布
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。
stackInt length:1581 Exception in thread "main" java.lang.StackOverflowError at jvm.StackSOF.stackLeak(StackSOF.java:11) at jvm.StackSOF.stackLeak(StackSOF.java:11)View Code 实验结果表明:在单线程下,无论是由于栈帧太大还是虚拟机栈容量太小,当内存无法分配时,虚拟机都是抛出StackOverflowError异常。
如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。
/** * 这时候不妨设置的大些 特别提示:如果你想尝试运行这段代码,记得保存当前工作,很可能电脑会卡死机 * -Xss4M */ public class StackOOM { private void notStop() { while (true) { } } public void stackLeakByThread() { while (true) { Thread thread = new Thread(new Runnable() { @Override public void run() { notStop(); } }); thread.start(); } } public static void main(String[] args) { StackOOM oom = new StackOOM(); oom.stackLeakByThread(); } }
运行结果:
我在windows环境下,出现内存使用爆满,电脑卡死,只能被迫重启电脑。
3. 方法区和运行时常量池溢出
方法区用于存放Class相关信息,基本思路就是运行时产生大量的类去填满方法区,直到溢出。
/** * 方法区内存10M 方法区最大内存10M * -XX:PermSize=10M -XX:MaxPermSize=10M */ public class MethodAreaOOM { static class OOMObject { } public static void main(String[] args) { while (true) { //使用了CFLIB这类字节码技术,有兴趣可以另外了解一下 Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(OOMObject.class); enhancer.setCallback(new MethodInterceptor() { public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { return methodProxy.invokeSuper(o, objects); } }); enhancer.create(); } } }
运行结果:
书中介绍会抛出异常 caused by: java.OutOfMemoryError: PermGen space ..... ..... 我自己执行时出现内存使用率迅速增长, 我顾及电脑会再次卡死就手动关闭了程序
4. 本机直接内存溢出
使用Unsage类的allocateMemory()方法来真正申请分配内存。
/** * 设置最大堆内存20M 最大直接内存10M * -Xmx20M -XX:MaxDirectMemorySize=10M */ public class DirectMemoryOOM { private static final int _1MB = 1024*1024; public static void main(String[] args) throws Exception{ Field field = Unsafe.class.getDeclaredFields()[0]; field.setAccessible(true); Unsafe unsafe = (Unsafe)field.get(null); while (true) { unsafe.allocateMemory(_1MB);//分配内存 } //执行后 360提示电脑虚拟内存不足 } }
运行结果:
Exception in thread "main" java.lang.OutOfMemoryError at sun.misc.Unsafe.allocateMemory(Native Method) at jvm.DirectMemoryOOM.main(DirectMemoryOOM.java:20)
本章小结
通过这一章的学习,我们明白了虚拟机中的内存是怎么划分的,哪部分区域、什么样的代码和操作可能导致内存溢出异常。虽然Java有垃圾收集机制,但内存溢出异常离我们仍然并不遥远,
本章只讲解了各个区域出现异常的原因,下一章会详细讲解Java垃圾收集机制的底层实现。
相关文章推荐
- Java内存区域与内存溢出异常-HotSpot虚拟机对象探秘
- 【深入Java虚拟机】之一:Java内存区域与内存溢出
- java内存区域与内存溢出
- Java虚拟机——Java内存区域与内存溢出
- Java内存区域与内存溢出
- JAVA内存区域与内存溢出相关设置
- jvm笔记1--Java内存区域与内存溢出
- Java内存区域与内存溢出异常
- 深入理解java虚拟机一:java内存区域与内存溢出
- Java内存区域与内存溢出异常-异常实战
- 【深入Java虚拟机】之一:Java内存区域与内存溢出
- JAVA内存区域与内存溢出相关设置
- 深入理解Java虚拟机1~内存区域与内存溢出
- Java 内存区域与内存溢出
- JVM:Java内存区域与内存溢出
- Java内存区域与内存溢出异常--HotSpot虚拟机对象探秘
- (JVM1)Java内存区域与内存溢出异常之二
- java内存区域与内存溢出
- 深入java虚拟机 1 java内存区域与内存溢出的异常
- Java基础--jvm(内存区域与内存溢出异常--运行时数据区域)