OutOfMemoryError异常

来源:互联网 发布:山西太原理工软件学院 编辑:程序博客网 时间:2024/06/03 18:06
一、堆溢出:1,实验:1)设置虚拟机启动参数(VM arguments):-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8注:如果使用命令行来执行程序,那么在Java命令之后加上这些即可2)// 实验一:内存溢出(Memory Overflow)public class HeapOOM {static class OOMObject{}public static void main(String[] args) {List<OOMObject> list = new ArrayList<HeapOOM.OOMObject>();while (true) {list.add(new OOMObject());}}}结果:Exception in thread "main" java.lang.OutOfMemoryError: Java heap space// 实验二:内存泄露(Memory Leak)public class testMemoryLeak{static Vector<Object> v = new Vector<Object>(10);public static void test() {for (int i = 1; i < 100; i++) {Object obj = new Object();v.add(obj);obj = null;}}public static void main(String[] args) {test();}}分析:属于静态集合类引起内存泄露说明:静态变量的生命周期和应用程序一致,所以静态变量引用的对象就不会被GC回收。解决方案:让静态变量失去对他们(obj)的引用,最简单的方法就是:把静态变量设为null2,注意:将堆的最小值-Xms参数与堆的最大值-Xmx参数设为一样,即可避免堆自动扩展。3,解决方案:1)内存泄露(Memory Leak):通过内存影像分析工具(eg:Eclipse Memory Analyzer)1>对dump出来的堆转储快照进行分析2>查看泄露对象到 GC Roots 的引用链2)内存溢出(Memory Overflow):1>检查虚拟机的堆参数(-Xms和-Xmx),并与机器的物理内存对比来判断是否可以调大堆的容量。2>检查代码:查看是否存在生命周期过长的对象,尝试优化代码,减少内存的消耗。二、虚拟机栈溢出:1,类型:1)如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出 StackOverFlow 异常2)如果虚拟机在扩展栈时无法申请到足够的内存空间,将抛出 OutOfMemoryError 异常2,注意:1)操作系统分配给每个进程的内存是有限的。操作系统提供的内存 = 堆容量 + 方法区容量 + 栈容量 + 其他2)多线程环境下,为每个线程的栈分配的内存越大,越容易产生内存溢出异常。3)由于建立过多的线程而导致的内存溢出的解决方案:1>减少线程数或更换64位虚拟机2>减少最大堆、减少栈容量来换取更多的线程4)栈容量由 -Xss参数设定三、方法区溢出:说明:方法区用于存放Class的相关信息,如类名、访问修饰符、常量池、方法的描述等发生的时机:当运行时有大量的类生成,而方法区没有足够的内存,此时方法区发生溢出发生的场景:1)在经常动态生成大量的类(Class)的应用中:Spring和Hibernate在对类进行增强时,都会使用到CGLib字节码增强技术,增强的类越多,就需要越大的方法区来保证动态生成的Class可以载入内存。2)大量JSP或者动态产生大量JSP文件的应用(JSP第一次运行时需要编译成Servlet类)

0 0
原创粉丝点击