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

Stella981
• 阅读 627

一、概念

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

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
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
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
java 内存溢出 栈溢出的原因与排查方法
1、内存溢出的原因是什么?内存溢出是由于没被引用的对象(垃圾)过多造成JVM没有及时回收,造成的内存溢出。如果出现这种现象可行代码排查:一)是否应用中的类中和引用变量过多使用了Static修饰如publicstaitcStudents;在类中的属性中使用static修
浪人 浪人
3年前
Android 内存泄露:详解 Handler 内存泄露的原因与解决方案
前言在Android开发中,内存泄露十分常见1.内存泄露的定义:本该被回收的对象不能被回收而停留在堆内存中2.内存泄露出现的原因:当一个对象已经不再被使用时,本该被回收但却因为有另外一个正在使用的对象持有它的引用从而导致它不能被回收。这就导致了内存泄漏。本文将详细讲解内存泄露的其中一种情况:在Handler中发生的内
Wesley13 Wesley13
3年前
JDK8中JVM堆内存划分
一:JVM中内存JVM中内存通常划分为两个部分,分别为堆内存与栈内存,栈内存主要用运行线程方法存放本地暂时变量与线程中方法运行时候须要的引用对象地址。JVM全部的对象信息都存放在堆内存中。相比栈内存,堆内存能够所大的多,所以JVM一直通过对堆内存划分不同的功能区块实现对堆内存中对象管理。堆内存不够最常见的错误就是OOM(OutOf
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这