随笔- 38  文章- 1  评论- 0  阅读- 15663 

内存泄露

当一个对象已经不需要再使用本该被回收时,另外一个正在使用的对象持有它的引用从而导致它不能被回收,这导致本该被回收的对象不能被回收而停留在堆内存中,这就产生了内存泄漏。时会出现内存持续上升的情况,容易导致内存溢出(OOM)。

在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点:   可达且无用【只占有引用】

  1. 首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;
  2. 其次,这些对象是无用的,即程序以后不会再使用这些对象。

 

 

出现原因

1、静态集合类引起内存泄漏:

2、当集合里面的对象属性被修改后,再调用remove()方法时不起作用。JDK1.8 貌似修正了引用对象修改参数,导致hashCode变更的问题。

3、监听器 Listener 各种连接 Connection;

4、内部类和外部模块的引用(尽量使用静态内部类);

5、单例模式(静态类持有引用,导致对象不可回收);

 

解决方法

1.尽量减少使用静态变量,或者使用完及时 赋值为 null。

2.明确内存对象的有效作用域,尽量缩小对象的作用域,能用局部变量处理的不用成员变量,因为局部变量弹栈会自动回收;

3.减少长生命周期的对象持有短生命周期的引用;

4.使用StringBuilder和StringBuffer进行字符串连接,Sting和StringBuilder以及StringBuffer等都可以代表字符串,其中String字符串代表的是不可变的字符串,后两者表示可变的字符串。如果使用多个String对象进行字符串连接运算,在运行时可能产生大量临时字符串,这些字符串会保存在内存中从而导致程序性能下降。

5.对于不需要使用的对象手动设置null值,不管GC何时会开始清理,我们都应及时的将无用的对象标记为可被清理的对象;

6.各种连接(数据库连接,网络连接,IO连接)操作,务必显示调用close关闭。

 

定位与解决

通过jstat命令查看GC总体情况,及各个区的使用率变化。

 

 

 

通过jmap生成堆转储快照,查看存活对象,它显示对象数量和占用byte大小。根据存活对象的不正常增长情况,分析程序中哪些地方用到了这种对象,也可以大致推断出可能的内存泄漏处。

 

 

 

非正常情况

 

 

-XX:+HeapDumpOnOutOfMemoryError

 

 

 

 posted on   小北呦  阅读(1355)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示