JVM内存泄漏导致内存溢出(OOM)的场景

一、概念

1. 内存泄漏:对象使用完之后,没有按照预期被GC回收,一直留在内存中

2. 内存溢出:大量对象一直留在内存中,导致内存不够用(OOM),影响正常的程序运行

二、内存泄漏的场景

1. 内存中数据量太大,比如一次性从数据库中取出来太多数据

2. 静态集合类中对对象的引用,在使用完后未清空(只把对象设为null,而不是从集合中移除),使JVM不能回收,即内存泄漏

3. 静态方法中只能使用全局静态变量,而如果静态变量又持有静态方法传入的参数对象的引用,会引起内存泄漏

4. 代码中存在死循环,或者循环过多,产生过多的重复的对象

5. JVM启动参数内存值设置过小

a. 堆内存:JVM默认为64M,-Xms堆的最小值, -Xmx堆的最大值,OutOfMemoryError: java heap space

b. 栈内存:-Xss,StackOverflowError,栈太深

c. 永久代内存:-XX:PermSize,-XX:MaxPermSize,OutOfMemoryError: PermGen space,加载的类过多

6. 监听器:addXXListener,没有remove

7. 各种连接没有关闭:例如数据库连接、网络连接

8. 单例模式:如果单例对象持有外部对象的引用,那么外部对象将不会被回收,引起内存泄漏

9. 一个类含有静态变量,这个类的对象就无法被回收

10. ThreadLocal

三、解决思路

1. 修改JVM启动参数,直接增加内存

2. 检查错误日志

3. 检查代码中有没有一次性查出数据库所有数据

4. 检查代码中是否有死循环

5. 检查代码中循环和递归是否产生大量重复对象

6. 检查List/Map等集合,是否未清除

7. 使用内存查看工具

四、代码优化

1. 主动释放无用的对象

2. 尽量使用StringBuilder代替String

3. 尽量少用静态变量,因为静态变量是类的,GC不会回收

4. 避免创建大对象和同时创建多个对象,例如数组,因为数组的长度是固定的

5. 对象池技术

五、JVM堆内存溢出后,其他线程可否继续工作?

1. 当前线程OOM后,如果终止,会发生GC,其他线程可以继续工作

2. 如果线程OOM后,没有终止,其他线程也会OOM

https://www.cnblogs.com/200911/p/3965108.html

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java 内存溢出 栈溢出的原因与排查方法

1、内存溢出的原因是什么?内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,造成的内存溢出。如果出现这种现象可行代码排查:一)是否应用中的类中和引用变量过多使用了Static修饰如publicstaitcStudents;在类中的属性中使用static修

Android 内存泄露:详解 Handler 内存泄露的原因与解决方案

前言在Android开发中,内存泄露十分常见1.内存泄露的定义:本该被回收的对象不能被回收而停留在堆内存中2.内存泄露出现的原因:当一个对象已经不再被使用时,本该被回收但却因为有另外一个正在使用的对象持有它的引用从而导致它不能被回收。这就导致了内存泄漏。本文将详细讲解内存泄露的其中一种情况:在Handler中发生的内