java内存泄露、内存溢出

 

java内存泄露、内存溢出

内存泄露

内存泄露是指程序中间动态分配了内存,但在程序结束时没有释放这部分内存,从而造成那部分内存不可用的情况,重启计算机可以解决,但也有可能再次发生内存泄露,内存泄露和硬件没有关系,它是由软件设计缺陷引起的。

发生情况及解决方法:

1.静态集合类,如HashMap 和Vector
静态集合类的生命周期和程序一致,一次集合对象不用时应及时将其设为Null。

2.各种连接,如数据库连接,网络连接,I/O连接。
连接不用时应将其Close,否则GC不会回收相应的对象。

3.监听器。
在释放对象时,必须删除相应的监听器。

4.变量的不合理作用于。若对象仅在局部使用,却被声明在更大的作用范围当中,就可能造成内存泄漏,或者没有及时的将对象设为null,也会造成内存泄漏。
对象声明,应该和其使用范围一致,并且使用结束后及时设为Null。

避免方法:

1) 尽早释放无用对象的引用。
好的办法是使用临时变量的时候,让引用变量在退出活动域后自动设置为null,暗示垃圾收集器来收集该对象,防止发生内存泄露。

2) 程序进行字符串处理时,尽量避免使用String,而应使用StringBuffer。

因为每一个String对象都会独立占用内存一块区域,如:

3) 尽量少用静态变量。因为静态变量是全局的,GC不会回收。

4) 避免集中创建对象尤其是大对象,如果可以的话尽量使用流操作。
JVM会突然需要大量内存,这时会触发GC优化系统内存环境;

5) 尽量运用对象池技术以提高系统性能。
生命周期长的对象拥有生命周期短的对象时容易引发内存泄漏,例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块进行处理,然后解决一块释放一块的策略。

6) 不要在经常调用的方法中创建对象,尤其是忌讳在循环中创建对象。
可以适当的使用hashtable,vector 创建一组对象容器,然后从容器中去取那些对象,而不用每次new之后又丢弃。

7) 优化配置

Java 内存溢出:

程序在运行过程中动态申请的内存空间不再使用后没有及时释放,从而很可能导致应用程序内存无线增长。更广义的内存泄露包括未对系统的资源的及时释放,比如句柄等。

区域

1.堆内存溢出 java.lang.OutOfMemoryError:Java heap space

2.栈溢出

3.方法区(包括常量池)溢出 java.lang.OutOfMemoryError: PermGen space 加载了过多的类,jar等

4.直接内存溢出

情况:

1、在程序中存在死循环,或者循环过多,而产生了过多重复的对象的实例;

2、存在对象的引用,使用完后没有清除,导致JAVA虚拟机不能回收;如集合的使用。

3、一次操作时,在内存中加载了大量的数据;(算法空间复杂度过高)

4.使用的第三方软件中的BUG;

5.启动参数内存值设定的过小;

原则上来说,在JAVA中,由于它的自动垃圾回收机制,出现内存溢出的可能性并不是很大。

排查:

1.检查代码中是否有死循环或递归调用。

2.检查是否有大循环重复产生新对象实体。

3.检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。

4.检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。

解决:

1.从代码层面进行优化完善,尽量避免该情况发生;

一:

1.对那些静态(static)的对象要特别留神,特别是类型为Map,List,Set的,静态的变量会一直驻存在内存中,生命周期比较长,不会被垃圾器回收。

2.对于代码,要审查是否生成了大量的冗余的对象,还有一些逻辑业务处理的类,
算法是否过于复杂,调整算法,对于代码认真审查,再仔细重构一遍代码,能提高代码质量,提高程序运行稳定性。

3.Java中的内存溢出大都是因为栈中的变量太多了。其实内存有的是。建议不用的尽量设成null以便回收,多用局部变量,少用成员变量。

4.在我的程序中对静态变量的优化后,使程序占用内存量至少提升了5k-10k。所以也不容忽视。

二: 还有就是String类相关的东西:

1.字符串累加的时候一定要用StringBuffer的append方法,不要使用+操作符连接两个字符串。差别很大。而且在循环或某些重复执行的动作中不要去创建String对象,因为String对象是要用StringBuffer对象来处理的,一个String对象应该是产生了 3个对象(大概是这样:))。

2.字符串length()方法来取得字符串长度的时候不要把length放到循环中,可以在循环外面对其取值。(包括vector的size方法)。特别是循环次数多的时候,尽量把length放到循环外面。

3 写代码的时候处理内存溢出

 

1

2

3

4

5

6

7

 

try{

//do sth

}catch (outofmemoryerror e){//可以用一个共通函数来执行.

system.out.print (“no memory! ”);

system.gc();

//do sth again

....

4.对于频繁申请内存和释放内存的操作,还是自己控制一下比较好,但是System.gc()的方法不一定适用,最好使用finallize强制执行或者写自己的finallize方法。 Java 中并不保证每次调用该方法就一定能够启动垃圾收集,它只不过会向JVM发出这样一个申请,到底是否真正执行垃圾收集,一切都是个未知数。

三.调整优化JVM,服务器配置(调整参数):

1) 设置-Xms、-Xmx相等;

2) 设置NewSize、MaxNewSize相等;

3) 设置Heap size, PermGen space(永久代空间)

#内存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值