zoukankan      html  css  js  c++  java
  • 内存溢出和内存泄露分析及解决方案

    一.内存溢出和内存泄露的区别与联系

      内存溢出 out of memory,指程序要求的内存超出了系统所能分配的范围,出现out of memory;比如申请一个int类型,但给了它一个int才能存放的数,就会出现内存溢出,或者是创建一个大的对象,而堆内存放不下这个对象,这也是内存溢出。

      内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间(指分配出去的内存无法被gc回收)。一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

      因此,我们从上面也可以推断出内存泄露可能会导致内存溢出。内存溢出会抛出异常,内存泄露不会抛出异常,大多数时候程序看起来是正常运行的。

    二.内存溢出和内存泄露的案例

    public class demo {//内存溢出案例
        public static void main(String[] args) {
            List<Object> list=new ArrayList<>();
            while(true){//申请的内存过大
                int[] temp=new int[1000];
                list.add(temp);
            }
        }
    }
    public class demo {//内存泄露案例
        public static void main(String[] args) {
            Vector<Object> v = new Vector<>(1000);
            for (int i = 1; i<1000; i++)
            {
                Object o = new Object();
                v.add(o);
                o = null;
            }
        }
    }

      JVM堆内存溢出:

        

        

      JVM栈内存溢出

         

        

    三.内存溢出或泄露原因分析

      分析堆内存溢出的原因可能如下:

        使用了大量的递归或无限递归(递归中用到了大量的新建的对象)

        使用了大量循环或死循环(循环中用到了大量的新建的对象)

        类中和引用变量过多使用了Static修饰 如public staitc Student s;在类中的属性中使用 static修饰的最好只用基本类型或字符串。如public static int i = 0; //public static String str;

        数组,List,Map中存放的是对象的引用而不是对象,因为这些引用会让对应的对象不能被释放,会大量存储在内存中。

      分析栈内存溢出的原因可能如下:   

        使用了大量的递归或无限递归

        使用了大量循环或死循环(如循环中不停调用方法)

        list,map,数组等长度过大等。

    四.出现内存溢出或内存泄露的解决方案

      1.修改JVM启动参数(-Xms,-Xmx),直接增加虚拟机内存。

      2.检查错误日志。

      3.使用内存查看工具查看内存使用情况(如jconsole)

      4.对代码进行仔细分析,找出可能发生内存溢出的位置。

      详细排查方案如下:

        检查在数据库中取的数据量是否超过内存

        检查是否有过大的集合或对象

        检查是死循环或递归是否会导致溢出

        检查是否有大量对象的创建是否会出现内存问题

        检查是否有大量的连接对象或监听器等未关闭

        ......

    五.在开发中应如何避免出现内存泄露

      1.尽量少使用枚举

        2.尽量使用静态内部类而不是内部类

        3.尽量使用轻量级的数据结构

        4.养成关闭连接和注销监听器的习惯

        5.谨慎使用static关键字

        6.谨慎使用单例模式

        ......

  • 相关阅读:
    Java内存区域
    spring学习之Bean
    记一次日本公司的Java面试
    java中打印输出数组内容的三种方式
    Java创建子类时构造器执行顺序
    转发&重定向
    Java继承
    GXOI&GZOI
    LCT能干啥???
    后缀自动机的一些应用
  • 原文地址:https://www.cnblogs.com/ywb-articles/p/10533648.html
Copyright © 2011-2022 走看看