zoukankan      html  css  js  c++  java
  • 【深入Java虚拟机】之三:内存溢出

    为了更直接的了解各区域,下面我们来看几个示例。

    1、Java 堆溢出

    下面的程中我们限制Java 堆的大小为20MB,不可扩展(将堆的最小值-Xms 参

    数与最大值-Xmx 参数设置为一样即可避免堆自动扩展),通过参数-XX:+HeapDump

    OnOutOfMemoryError 可以让虚拟机在出现内存溢出异常时Dump 出当前的内存堆转储

    快照以便事后进行分析。

    参数设置如下



     



     


     Java 堆内存的OutOfMemoryError异常是实际应用中最常见的内存溢出异常情况。出现Java 堆内存溢出时,异常堆栈信息“java.lang.OutOfMemoryError”会跟着进一步提示“Java heap space”。要解决这个区域的异常,一般的手段是首先通过内存映像分析工具(如Eclipse Memory Analyzer)对dump 出来的堆转储快照进行分析,重点是确认内存中的对象是否是必要的,也就是要先分清楚到底是出现了内存泄漏(Memory Leak)还是内存溢出(Memory Overflow)。图2-5 显示了使用Eclipse Memory Analyzer 打开的堆转储快照文件。

    如果是内存泄漏,可进一步通过工具查看泄漏对象到GC Roots 的引用链。于是就能找到泄漏对象是通过怎样的路径与GC Roots 相关联并导致垃圾收集器无法自动回收

    它们的。掌握了泄漏对象的类型信息,以及GC Roots 引用链的信息,就可以比较准确地定位出泄漏代码的位置。

    如果不存在泄漏,换句话说就是内存中的对象确实都还必须存活着,那就应当检查虚拟机的堆参数(-Xmx 与-Xms),与机器物理内存对比看是否还可以调大,从代码上

    检查是否存在某些对象生命周期过长、持有状态时间过长的情况,尝试减少程序运行期的内存消耗。

    以上是处理Java 堆内存问题的简略思路,处理这些问题所需要的知识、工具与经验在后面的几次分享中我会做一些额外的分析。

    2、java栈溢出 

    Java代码  收藏代码
    1. package com.yhj.jvm.memory.stack;  
    2. /** 
    3.  * @Described:栈层级不足探究 
    4.  * @VM args:-Xss128k 
    5.  * @author YHJ create at 2011-11-12 下午08:19:28 
    6.  * @FileNmae com.yhj.jvm.memory.stack.StackOverFlow.java 
    7.  */  
    8. public class StackOverFlow {  
    9.     private int i ;  
    10.     public void plus() {  
    11.        i++;  
    12.        plus();  
    13.     }  
    14.     /** 
    15.      * @param args 
    16.      * @Author YHJ create at 2011-11-12 下午08:19:21 
    17.      */  
    18.     public static void main(String[] args) {  
    19.        StackOverFlow stackOverFlow = new StackOverFlow();  
    20.        try {  
    21.            stackOverFlow.plus();  
    22.        } catch (Exception e) {  
    23.            System.out.println("Exception:stack length:"+stackOverFlow.i);  
    24.            e.printStackTrace();  
    25.        } catch (Error e) {  
    26.            System.out.println("Error:stack length:"+stackOverFlow.i);  
    27.            e.printStackTrace();  
    28.        }  
    29.     }  
    30. }   

    3、 方法区溢出 

    Java代码  收藏代码
    1. package com.yhj.jvm.memory.methodArea;  
    2. import java.lang.reflect.Method;  
    3. import net.sf.cglib.proxy.Enhancer;  
    4. import net.sf.cglib.proxy.MethodInterceptor;  
    5. import net.sf.cglib.proxy.MethodProxy;  
    6. /** 
    7.  * @Described:方法区溢出测试 
    8.  * 使用技术 CBlib 
    9.  * @VM args : -XX:PermSize=10M -XX:MaxPermSize=10M 
    10.  * @author YHJ create at 2011-11-12 下午08:47:55 
    11.  * @FileNmae com.yhj.jvm.memory.methodArea.MethodAreaOutOfMemory.java 
    12.  */  
    13. public class MethodAreaOutOfMemory {  
    14.     /** 
    15.      * @param args 
    16.      * @Author YHJ create at 2011-11-12 下午08:47:51 
    17.      */  
    18.     public static void main(String[] args) {  
    19.        while(true){  
    20.            Enhancer enhancer = new Enhancer();  
    21.            enhancer.setSuperclass(TestCase.class);  
    22.            enhancer.setUseCache(false);  
    23.            enhancer.setCallback(new MethodInterceptor() {  
    24.               @Override  
    25.               public Object intercept(Object arg0, Method arg1, Object[] arg2,  
    26.                      MethodProxy arg3) throws Throwable {  
    27.                   return arg3.invokeSuper(arg0, arg2);  
    28.               }  
    29.            });  
    30.            enhancer.create();  
    31.        }  
    32.     }  
    33. }  
    34. /** 
    35.  * @Described:测试用例 
    36.  * @author YHJ create at 2011-11-12 下午08:53:09 
    37.  * @FileNmae com.yhj.jvm.memory.methodArea.MethodAreaOutOfMemory.java 
    38.  */  
    39. class TestCase{  
    40.      
    41. }  
     
    4、常量池溢出(常量池都有哪些信息,我们在后续的JVM类文件结构中详细描述) 
    Java代码  收藏代码
    1. import java.util.ArrayList;  
    2. import java.util.List;  
    3. /** 
    4.  * @Described:常量池内存溢出探究 
    5.  * @VM args : -XX:PermSize=10M -XX:MaxPermSize=10M 
    6.  * @author YHJ create at 2011-10-30 下午04:28:30 
    7.  * @FileNmae com.yhj.jvm.memory.constant.ConstantOutOfMemory.java 
    8.  */  
    9. public class ConstantOutOfMemory {  
    10.     /** 
    11.      * @param args 
    12.      * @throws Exception 
    13.      * @Author YHJ create at 2011-10-30 下午04:28:25 
    14.      */  
    15.     public static void main(String[] args) throws Exception {  
    16.        try {  
    17.            List<String> strings = new ArrayList<String>();  
    18.            int i = 0;  
    19.            while(true){  
    20.               strings.add(String.valueOf(i++).intern());  
    21.            }  
    22.        } catch (Exception e) {  
    23.            e.printStackTrace();  
    24.            throw e;  
    25.        }  
    26.     }  

    5、直接内存溢出 

    Java代码  收藏代码
    1. package com.yhj.jvm.memory.directoryMemory;  
    2. import java.lang.reflect.Field;  
    3. import sun.misc.Unsafe;  
    4. /** 
    5.  * @Described:直接内存溢出测试 
    6.  * @VM args: -Xmx20M -XX:MaxDirectMemorySize=10M 
    7.  * @author YHJ create at 2011-11-12 下午09:06:10 
    8.  * @FileNmae com.yhj.jvm.memory.directoryMemory.DirectoryMemoryOutOfmemory.java 
    9.  */  
    10. public class DirectoryMemoryOutOfmemory {  
    11.    
    12.     private static final int ONE_MB = 1024*1024;  
    13.     private static int count = 1;  
    14.    
    15.     /** 
    16.      * @param args 
    17.      * @Author YHJ create at 2011-11-12 下午09:05:54 
    18.      */  
    19.     public static void main(String[] args) {  
    20.        try {  
    21.            Field field = Unsafe.class.getDeclaredField("theUnsafe");  
    22.            field.setAccessible(true);  
    23.            Unsafe unsafe = (Unsafe) field.get(null);  
    24.            while (true) {  
    25.               unsafe.allocateMemory(ONE_MB);  
    26.               count++;  
    27.            }  
    28.        } catch (Exception e) {  
    29.            System.out.println("Exception:instance created "+count);  
    30.            e.printStackTrace();  
    31.        } catch (Error e) {  
    32.            System.out.println("Error:instance created "+count);  
    33.            e.printStackTrace();  
    34.        }  
    35.    
    36.     }  
    37.    
    38. }  
  • 相关阅读:
    crowd在更改IP后无法登录的问题
    VMware虚拟机中为Linux 添加虚拟硬盘(VirtualBox方法类似)
    虚拟机virtualbox中挂载新硬盘
    下载谷歌浏览器(Chrome)扩展离线安装包crx文件最简单的方法
    Chrome神器Vimium快捷键学习记录
    Chrome好用的扩展插件
    虚拟内存,MMU/TLB,PAGE,Cache之间关系
    ARM“庖丁解牛”之存储器管理单元MMU
    MMU——存储器管理单元
    我的vim配置---jeffy-vim-v2.3.tar
  • 原文地址:https://www.cnblogs.com/wytiger/p/10407184.html
Copyright © 2011-2022 走看看