zoukankan      html  css  js  c++  java
  • jvm中除了程序计数器其他运行时区域的OutOfMemoryError

    1. java堆溢出测试

    java堆用于存储对象实例,只要不断创建对象,并且保证GC Roots到对象之间的可达路径来避免垃圾回收机制清理这些对象,那么当对象的达到堆的容量最大值滞后就会产生outofmemoryerror;

    通过参数:-Xms20m 最小堆大小; -Xmx20m 最大堆大小;  -XX:+HeapDumpOnOutOfMemoryError  虚拟机在内存溢出异常时Dump出当前的内存堆转储快照

    具体配置:

    -verbose:gc -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:SurvivorRatio=8

    代码:

     1 package javaTest;
     2 
     3 import java.io.Serializable;
     4 import java.util.LinkedList;
     5 import java.util.List;
     6 
     7 public class Portal {
     8 
     9     /**
    10      * vm args : -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
    11      * @param args
    12      */
    13     public static void main(String[] args) {
    14         System.out.println("test heap memory dump");
    15         
    16         
    17         List<HeapOOM> lists = new LinkedList<HeapOOM>();
    18         
    19         while(true){
    20             lists.add(new HeapOOM());
    21         }
    22         
    23         
    24         
    25     }
    26     
    27     public static class HeapOOM implements Serializable{
    28         
    29         /**
    30          * 
    31          */
    32         private static final long serialVersionUID = -7562967142125991489L;
    33         
    34         private int count;
    35 
    36         public int getCount() {
    37             return count;
    38         }
    39 
    40         public void setCount(int count) {
    41             this.count = count;
    42         }
    43         
    44         
    45     }
    46 
    47 }
    View Code

    异常:

    注意:一定要辨别是内存泄露(memory Leak)还是内存溢出(memory Overflow)

    2. java虚拟机栈和本地方法栈溢出

    如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverFlowError异常;

    如果虚拟机的扩展栈无法申请到足够的内存空间,则抛出OutOfMemoryError异常;

    参数:-Xoss 设置本地方法栈大小;-Xss 设置虚拟机房发展大小

    具体设置:

    -Xss128k

    代码:

     1 package javaTest;
     2 
     3 public class StackOverFlowTest {
     4     
     5     /**
     6      * vm args : -Xss128K
     7      * @param args
     8      */
     9     public static void main(String[] args){
    10         
    11         OverFlowStackClass model = new OverFlowStackClass();
    12         
    13         try{
    14             model.stackLeak();
    15         }catch(Throwable ex){
    16             System.out.println("最大深度:"+String.valueOf(model.stackLength));
    17             throw ex;
    18         }
    19         
    20         
    21         
    22         
    23         
    24         
    25     }
    26     
    27     static class OverFlowStackClass{
    28         public int stackLength=1;
    29         
    30         public void stackLeak(){
    31             stackLength++;
    32             stackLeak();
    33         }
    34     }
    35     
    36     
    37 
    38 }
    View Code

    异常:

    如果是创建过多的线程导致内存溢出,在不减少线程数量或者更换64bit虚拟机的情况下,就只能通过减少最大堆和减少虚拟机栈容量来换取更多的线程,如果没有这方便的处理经验,这种通过增加线程挤占java虚拟机栈的方式来验证java栈的内存溢出(outofmemoryerror)的场景是很难想到的;

    本人电脑是windows这里对于这种情况就不做演示了,代码实现其实就是疯狂的创建新的线程来实现。java栈的内存溢出;

    3. 方法区和运行时常量池的内存溢出

    String.intern();是一个Native方法,它的作用是 如果字符串常量池中已经包含一个等于此String对象的字符串,则返回字符串常量池中的这个字符串;否则创建一个新的对象,该对象添加到常量池中,最后返回此字符串的引用。

    参数:-XX:PermSize  -XX:MaxPermSize

    具体参数:

    -XX:PermSize=10M -XX:MaxPermSize=10M

    代码:

     1 package javaTest;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 
     6 public class MethodOutOfMemoryError {
     7     
     8     /** 
     9      * vm args: -XX:PermSize=10M -XX:MaxPermSize=10M
    10      * @param args
    11      */
    12     public static void main(String[] args){
    13         
    14         List<String> lists = new ArrayList<String>();
    15         
    16         int i=0;
    17         while(true){
    18             lists.add(String.valueOf(i++).intern());
    19         }
    20         
    21     }
    22 
    23 }
    View Code

    异常:

    1.7+以上版本不会出现异常了,可以通过:-verbose:gc查看GC的回收过程;

    4. 本机直接内存溢出

    参数:-XX:MaxDirectMemorySize 制定可以使用的机器内存的大小

    具体运行参数:

    -Xmx10m -XX:MaxDirectMemorySize=10m

    代码:

     1 package javaTest;
     2 
     3 import java.lang.annotation.Annotation;
     4 import java.lang.reflect.Field;
     5 
     6 import sun.misc.Unsafe;
     7 
     8 public class DirectMemoryTest {
     9 
    10     private static final int _1MB = 1024*1024;
    11     
    12     /**
    13      * vm agrs: -Xmx10m -XX:MaxDirectMemorySize=10m
    14      * @param args
    15      * @throws IllegalAccessException 
    16      * @throws IllegalArgumentException 
    17      */
    18     public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException{
    19         
    20         System.out.println(_1MB);
    21         
    22         Field unsafeField = Unsafe.class.getDeclaredFields()[0];
    23         unsafeField.setAccessible(true);
    24         Unsafe unsafe = (Unsafe)unsafeField.get(null);
    25         while(true){
    26             unsafe.allocateMemory(_1MB);
    27         }
    28         
    29         
    30         
    31         
    32     }
    33 }
    View Code

    异常:

    虽然java有垃圾回收机制,但是内存溢出对我们来说也是家常便饭,所以要明白什么情况下导致内存溢出,从而尽量避免内存溢出的发生;

     如果出现内存异常根据堆栈信息可以快速排查是什么原因;

     

  • 相关阅读:
    Promise原理实现(一):前置知识点
    移动端禁用缩放
    多条命令同时执行的包concurrently
    通过面试题学JavaScript知识(1)
    移动设备适配
    css 文本溢出显示省略号
    变量对象的理解
    7.10 日志
    7.9 日志
    JMETER接口测试之自动化环境的配置
  • 原文地址:https://www.cnblogs.com/linuxone/p/7102167.html
Copyright © 2011-2022 走看看