打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
面试准备之内存泄露与溢出


面试准备之内存泄露与溢出

http://www.cnblogs.com/wabi87547568/p/5284299.html

一、基本概念

  内存泄露:指程序中动态分配内存给一些临时对象,但是对象不会被GC所回收,它始终占用内存。即被分配的对象可达但已无用

  内存溢出:指程序运行过程中无法申请到足够的内存而导致的一种错误。内存溢出通常发生于OLD段或Perm段垃圾回收后,仍然无内存空间容纳新的Java对象的情况。

  从定义上可以看出内存泄露是内存溢出的一种诱因,不是唯一因素。

 

二、内存泄露的原因

  1、静态集合类引起的内存泄露

       例如HashMap、Vector等的使用出现内存泄露。在全局静态map中缓存局部变量,且没有清空操作,随着时间的推移,这个map会越来越大,造成内存泄露。修改hashset中对象的参数值,且参数是计算哈希值的字段,修改后的哈希值与最初存储进HashSet集合中时的哈希值不同,导致返回找不到对象的结果,无法从HashSet集合中删除当前对象,造成内存泄露。

    2、当集合里面的对象属性被修改后,再调用remove()方法不起作用

    3、监听器 
      在java 编程中,我们都需要和监听器打交道,通常一个应用当中会用到很多监听器,我们会调用一个控件的诸如addXXXListener()等方法来增加监听器,但往往在释放对象的时候却没有记住去删除这些监听器,从而增加了内存泄漏的机会。

    4、各种连接 
      比如数据库连接(dataSourse.getConnection()),网络连接(socket)和io连接,除非其显式的调用了其close()方法将其连接关闭,否则是不会自动被GC 回收的。

    5、内部类和外部模块等的引用 
      内部类的引用是比较容易遗忘的一种,而且一旦没释放可能导致一系列的后继类对象没有释放。

    6、单例模式 
      不正确使用单例模式是引起内存泄露的一个常见问题,单例对象在被初始化后将在JVM的整个生命周期中存在(以静态变量的方式),如果单例对象持有外部对象的引用,那么这个外部对象将不能被jvm正常回收,导致内存泄露

 

三、内存溢出的原因

  1、堆内存溢出

     在jvm规范中,堆中的内存是用来生成对象实例和数组的。

         如果细分,堆内存还可以分为年轻代和年老代,年轻代包括一个eden区和两个survivor区。

         当生成新对象时,内存的申请过程如下:

            a、jvm先尝试在eden区分配新建对象所需的内存;

            b、如果内存大小足够,申请结束,否则下一步;

            c、jvm启动youngGC,试图将eden区中不活跃的对象释放掉,释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区;

            d、Survivor区被用来作为Eden及old的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区;

            e、 当OLD区空间不够时,JVM会在OLD区进行full GC;

            f、full GC后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”:

  2、方法区内存溢出

     在jvm规范中,方法区主要存放的是类信息、常量、静态变量等。

         所以如果程序加载的类过多,或者使用反射、gclib等这种动态代理生成类的技术,就可能导致该区发生内存溢出,一般该区发生内存溢出时的错误信息为:outOfMemoryError:permgem space

  3、线程栈溢出java.lang.StackOverflowError

         线程栈时线程独有的一块内存结构,所以线程栈发生问题必定是某个线程运行时产生的错误。

         一般线程栈溢出是由于递归太深或方法调用层级过多导致的。

         发生栈溢出的错误信息为: java.lang.StackOverflowError

 

四、内存泄露的建议

  1、尽早释放无用对象的引用

  2、使用字符串处理,避免使用String,应大量使用StringBuffer,每一个String对象都得独立占用内存一块区域

  3、尽量少用静态变量,因为静态变量存放在永久代(方法区),永久代基本不参与垃圾回收

  4、避免在循环中创建对象

  5、开启大型文件或从数据库一次拿了太多的数据很容易造成内存溢出,所以在这些地方要大概计算一下数据量的最大值是多少,并且设定所需最小及最大的内存空间值。 

 

分类: 面试准备
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
JVM 详解,大白话带你认识 JVM
Java GC工作原理以及Minor GC、Major GC、Full GC简单总结
JVM(Java虚拟机)优化大全和案例实战
Java系列笔记(3)
JVM系列(八):堆(Heap)的相关知识介绍
如何调优JVM
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服