• Java内存溢出及分析


      对于内存溢出,首先想到的是C语言,其实不然,java中也有各种的内存溢出。对于java程序员,在虚拟即中,不需要为每一个新建对象去delete/free内存,不容易出现内存溢出。但是,正

    是由于这种机制,java中如果出现了内存溢出将是一个很麻烦的事情,所以,对java虚拟机的内存使用的掌握能很好的帮助你排除问题。

      java内存有几种:程序计数器,虚拟机栈,方法常量区,堆,本地方法栈,直接内存。既然分析内存溢出,那就从这几种内存逐一分析。

      1,程序计数器:是一个较小的内存空间,是但钱线程的字节码行号指示器,这个不会出现内存溢出。

      2,虚拟即栈:虚拟即栈抛出的异常叫做StackOverFlowError异常,指的就是栈内存溢出。虚拟机栈内存溢出主要又两个原因:

        (1)栈深度超过限制。jvm虚拟机对虚拟机栈是有大小限制的,如果单一性线程的栈深度超过了这限制,会抛出StackOverFlowError(其中,每个栈的栈大小也影响这个限制的,比如在一个栈中只做一个复制操作栈深度超过10000就溢出了,但是如果一个栈中还定义了很多变量,分配了一些内存,可能超过6000就会溢出)

      如以下代码(测试):

    public class Main {
        private int stackLength = 1;
        
        public void stackLeak()
        {
            stackLength ++;
            stackLeak();
        }
        
        public static void main(String[]args)
        {
            Main main = new Main();        
            try
            {
                main.stackLeak();
            }
            catch(Error e)
            {
                System.out.println("stack length:" + main.stackLength);
                throw e;
            }
        }
    }

        输出结果:

    stack length:6745
    Exception in thread "main" java.lang.StackOverflowError
        at Main.stackLeak(Main.java:12)
        at Main.stackLeak(Main.java:13)

        (2)虚拟机在扩展是无法分配到足够的内存。

      3,方法常量区。你可以通过以下设置 -XX:PermSize=3M -XX:MaxPermSize=3M 然后在项目中加载大量的类,即会产生内存溢出,泄漏信息为 PermGen space.或者在常量去加入大

    量数据也可能会报以上错误。不过在jdk1.7及以上版本,通过String.intern()方法并不会把常量去挤破,因为常量区存放的是新建字符串的引用。

      

      4,堆。堆溢出是最常见的内存溢出情况。堆中存放的是对象的信息。如果项目中产生的对象过大,又由于彼此引用而不能被GC回收时,就会出现内存溢出。举例看下具体情况:

        代码:

    public class Test {
        public static void main(String[]args)
        {
            List<People> list = new ArrayList<People>();
            
            while(true)
            {
                list.add(new People());
            }
            
        }
        
        public static class People {
    
            public String name = "zeng";
            public int age = 24;
            
        }
    
    }

    输出:

    java.lang.OutOfMemoryError: Java heap space
    Dumping heap to java_pid16912.hprof ...
    Heap dump file created [76764870 bytes in 0.978 secs]
    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at Test.main(Test.java:12)

        对于堆溢出,情况主要有两种,一是对象太多,java内存不够用,这是可以通过设置堆内存大小来调节,如:Xms500m,Xmx1000m,来给堆分配较大的内存。

            第二种就不是那么好弄,很多对象本身你是不用的,但是由于又被其它对象引用,导出gc没法回收。

      5,本地方法栈。这个不受虚拟机管理,但是操作系统本事是有内存限制的。太大也会导致内存泄漏。

      6,直接内存。直接内存同样不受虚拟机管理,同样受操作系统限制,如果默认则和堆内存一样,同样也可以自己设置,如:-XX:MaxDirectMemorySize=1000m

    通过以上几种分析:发现如果出现内存泄漏,最可能的原先是由于堆溢出。这个也可以从异常信息分析出

        OutOfMemory - java heap space:堆溢出

      OutOfMemory -PerGem space:方法常量区溢出

      StackOverFlowError.: 栈溢出

      至于其余几种溢出,可以通过分析操作系统内存大小限制以及设置的堆内存,栈内存来判断。

  • 相关阅读:
    排序函数
    Wooden Sticks
    Tian Ji -- The Horse Racing
    error
    Java学习笔记七——数组工具类Arrays
    java学习笔记六——数组
    Java学习笔记五——流程控制
    Java学习笔记四——运算符
    Java学习笔记三——数据类型
    Java学习笔记二——标识符和关键字
  • 原文地址:https://www.cnblogs.com/2015zzh/p/4807667.html
Copyright © 2020-2023  润新知