当前位置: 首页 > news >正文

Jvm之内存泄漏

1 内存溢出

1.1  概念

java.lang.OutOfMemoryError,是指程序在申请内存时,没有足够的内存空间供其使用,出现OutOfMemoryError。产生该错误的原因主要包括:JVM内存过小。程序不严密,产生了过多的垃圾。

程序体现:

  • 内存中加载的数据量过于庞大,如一次从数据库取出过多数据。
  • Cglib 不断创建新类
  • 大量 JSP 或动态产生 JSP 文件的应用
  • 集合类中有对对象的引用,使用完后未清空,使得JVM不能回收。
  • 代码中存在死循环或循环产生过多重复的对象实体。
  • 使用的第三方软件中的BUG。
  • 启动参数内存值设定的过小。

错误提示:

  • tomcat:java.lang.OutOfMemoryError: PermGen space
  • tomcat:java.lang.OutOfMemoryError: Java heap space
  • weblogic:Root cause of ServletException java.lang.OutOfMemoryError
  • resin:java.lang.OutOfMemoryError
  • java:java.lang.OutOfMemoryError

1.2 解决办法

  • 增加JVM的内存大小。具体可参考:jvm之内存调优_jvm内存调优-CSDN博客
  • 优化程序,释放垃圾。主要思路就是避免程序体现上出现的情况。避免死循环,防止一次载入太多的数据,提高程序健壮型及时释放。因此,从根本上解决Java内存溢出的唯一方法就是修改程序,及时地释放没用的对象,释放内存空间。

1.3 内存溢出排查

内存溢出的排查过程通常包括以下几个步骤:

1.3.1 检查JVM崩溃日志:

  • 当JVM发生崩溃时,会生成相应的错误日志文件,如`hs_err_pid.log`。这些日志文件包含了堆栈信息、线程状态和系统信息。通过在JVM启动时设置`-XX:ErrorFile`参数,可以将错误日志输出到指定的文件中。

1.3.2 代码审查:

  • 仔细检查新上线的代码,寻找可能导致内存溢出的潜在问题,如死循环、慢SQL或大数据量查询等。

1.3.3 内存溢出dump文件分析:

  • 在JVM参数中设置`XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath`,以便在内存溢出时生成dump文件。这些文件的名称通常是`xxx.hprof`。之后,可以使用 Eclipse Memory Analyzer (MAT)对这些dump文件进行分析和诊断。

1.3.4 内存泄露分析:

  • 在MAT中打开dump文件,并进入“Leak Suspects”选项卡。在这里,你可以看到可能引起内存泄露的问题,以及它们占用的内存大小。进一步的分析可以帮助定位问题的根源。

以实际案例为例,如果在一个Java应用中观察到大量dubbo线程阻塞,并且JVM堆内存的老年代和新生代都达到了高负载,那么很可能是发生了内存溢出。在上述案例中,日志显示老年代几乎满了,而年轻代由于无法接收老年代的对象而导致频繁的Young GC,最终导致了堆内存溢出。此外,通过对dump文件的分析,可以找到具体的内存泄露点,从而确定问题的根本原因。

2 内存泄漏

Memory Leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。
在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点:

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

如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。对于内存泄露的处理页就是提高程序的健壮型,因为内存泄露是纯代码层面的问题。

2.1 泄漏分类

  • 经常发生:发生内存泄露的代码会被多次执行,每次执行,泄露一块内存;
  • 偶然发生:在某些特定情况下才会发生;
  • 一次性:发生内存泄露的方法只会执行一次;
  • 隐式泄露:一直占着内存不释放,直到执行结束;严格的说这个不算内存泄露,因为最终释放掉了,但是如果执行时间特别长,也可能会导致内存耗尽。

2.2 导致内存泄漏的常见原因

  • 循环:过多或者死循环导致产生了大量对象
  • 静态集合类:引起的内存泄漏,因为静态集合类的生命周期和JVM是一致的。
  • 单例模式: 如果单例对象引用了外部对象,会导致该外部对象一直不回被回收。因为单例的的静态属性会让对象的生命周期和JVM一致。
  • 变量的不合理作用域,如下:
> public class UsingRandom {        private String msg;public void receiveMsg(){readFromNet();// 从网络中接受数据保存到msg中saveDB();// 把msg保存到数据库中}
}
//如上面这个伪代码,通过readFromNet方法把接受的消息保存在变量msg中,然后调用saveDB方法把msg的内容保存到数据库中,此时msg已经就没用了,由于msg的生命周期与对象的生命周期相同,此时msg还不能回收,因此造成了内存泄漏。
//实际上这个msg变量可以放在receiveMsg方法内部,当方法使用完,那么msg的生命周期也就结束,此时就可以回收了。还有一种方法,在使用完msg后,把msg设置为null,这样垃圾回收器也会回收msg的内存空间。
  • 数据连接: 像IO,socket连接他们必须被显示的close掉,否则不回被GC回收。
  • 内部类:对象被外部对象长期持久,会导致外部类也无法被回收
  • 哈希值改变: 当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了。因为,当修改后,所得的哈希值与最初存储进HashSet集合中时的哈希值就不同了。在这种情况下,即使用contains()方法,也将返回找不到对象的结果,但是HashSet却一直持有修改前的对象的实例,导致不能被GC,造成内存泄露。
  • 监听器和回调: 在Java语言中, 往往呢会使用到监听器 ,一个应用可能会使用到多个监听器。 比如说, 在我们Java Web中有底层的网络监听器listener ,监听器的作用就是去监听指定的类或者对象他产生的行为 ,从而做出对应的响应, 因为监听器往往都是全局存在的, 如果对于监听器中所使用这些对象或者是变量 ,你没有有效的控制的话 ,很容易产生内存泄露 。
  • 缓存: 内存泄漏的另一个常见来源是缓存。举个例子,我们有时候为了减少与db的交互次数,会将查询出的对象实例放入缓存中,但是常常会忘记对这个缓存进行管理。比如忘记限制缓存大小。

对于这个问题,可以使用WeakHashMap代表缓存,此种Map的特点是,当除了自身有对key的引用外,此key没有其他引用那么此map会自动丢弃此值。

2.3 内存泄漏排查

2.3.1 查看JVM状态

1)查看虚拟机进程,找到需要监控的进程ID

使用 jps | ps 找到对应的进程ID

jps:jps -l
ps:ps -aux | grep java

2)使用 jstat实时的查看一下当前程序的资源和性能。
命令:

jstat -gcutil 进程ID 1000
//每1000毫秒查询一次,一直查。gcutil的意思是已使用空间站总空间的百分比。

执行结果:

2.3.2 定位问题

2.3.2.1 dump文件分析

1)使用 jmap查看存活对象,并生成dump文件。

jmap命令格式:

jmap [ option ] vmid

使用命令如下:

 jmap -histo:live 28558| head -20 
//查看示Java堆中存活对象的统计信息,包括:对象数量、占用内存大小(单位:字节)和类的完全限定名,

生成heap dump文件:

jmap -dump:live,format=b,file=heap.hprof 3514  

2)Java heap分析工具

  • Ecplise用MAT插件
  • Idea安装Jprofiler进行分析
  • 堆Dump可视化分析在线工具: https://heaphero.io/

3)JVM调优常用工具:
 JVM调优的在线网站_java 堆分析网址-CSDN博客

相关文章:

Jvm之内存泄漏

1 内存溢出 1.1 概念 java.lang.OutOfMemoryError,是指程序在申请内存时,没有足够的内存空间供其使用,出现OutOfMemoryError。产生该错误的原因主要包括:JVM内存过小。程序不严密,产生了过多的垃圾。 程序体现: 内…...

尚硅谷webpack5笔记2

Loader 原理 loader 概念 帮助 webpack 将不同类型的文件转换为 webpack 可识别的模块。 loader 执行顺序 分类pre: 前置 loadernormal: 普通 loaderinline: 内联 loaderpost: 后置 loader执行顺序4 类 loader 的执行优级为:pre > normal > inline > post 。相…...

笔记本Win 10系统查看电池健康状况

博主最近换了个笔记本电池,之前的电池容量明显变小了很多,而且出现了轻微鼓包的情况。所以用gpt问了一下怎么用系统的方法查看电池情况。 在Windows 10系统中,您可以通过以下步骤来查看笔记本电脑电池的健康状况: 打开命令提示符&…...

算法--动态规划(线性DP、区间DP)

这里写目录标题 tip数组下标从0开始还是从1开始 数学三角形介绍算法思想例题代码 最长上升子序列介绍算法思想例题代码 最长公共子序列介绍算法思想例题代码 tip 数组下标从0开始还是从1开始 如果代码中涉及到数组下标为i-1(有时候哪怕不是同一个数组也符合情况&am…...

【ArcGIS】统计格网中不同土地利用类型占比

基于ArcGIS统计格网中不同土地利用类型占比 数据准备ArcGIS操作步骤1、创建渔网(Create Fishnet)2、建立唯一标识3、选择格网4、提取不同类别土地利用类型5、各类用地面积计算 参考另:可能出现的问题总结Q1:ArcGIS获取唯一值&…...

算法竞赛实用板子

一、声明 自用版参考acwing&#xff0c;致力于实用、好用&#xff0c;板子中有个人理解&#xff0c;持续更新。 二、开板 1.快排 void quick_sort(int q[],int l,int r) {if(l>r)return; //出口int il-1,jr1,xq[lr>>1]; //分治方法while(i<j){do i;w…...

RPA中国 x UiPath | 第六届RPA极客挑战赛,3月16日上海开赛!

随着人工智能技术的不断进步以及数字化转型的深入&#xff0c;企业对于高效、精准、自动化的业务流程需求日益迫切。RPA技术作为连接人类工作与机器操作的桥梁&#xff0c;正逐渐从规则驱动发展为智能决策的助手。 由RPA中国联合UiPath共同主办的【第六届RPA极客挑战赛】将于2…...

算法打卡day5|哈希表篇01|Leetcode 242.有效的字母异位词 、19.删除链表的倒数第N个节点、202. 快乐数、1. 两数之和

哈希表基础知识 哈希表 哈希表关键码就是数组的索引下标&#xff0c;然后通过下标直接访问数组中的元素&#xff1b;数组就是哈希表的一种 一般哈希表都是用来快速判断一个元素是否出现集合里。例如要查询一个名字是否在班级里&#xff1a; 要枚举的话时间复杂度是O(n)&…...

『python爬虫』xpath变化导致无法找到指定元素(持续更新中~)

目录 xpath变化的原因1. 语言设置2. 窗口大小n. 待添加~总结 欢迎关注 『python爬虫』 专栏&#xff0c;持续更新中 欢迎关注 『python爬虫』 专栏&#xff0c;持续更新中 xpath变化的原因 XPath 可能会出现变化的原因有很多&#xff0c;以下是一些常见的情况&#xff1a; 网页…...

人大金仓数据库Kingbase服务SQL基础操作手册

1 kingbase服务 1.1 查看kingbase数据库服务进程 ps -ef|grep kingbase1.2 命令启动kingbase数据库服务 # /opt/Kingbase/ES/V8 为金仓安装目录 # /opt/Kingbase/ES/V8/data 为金仓数据目录 # sys_ctl是数据库服务器启停命令&#xff0c;通过-D选项来来指定数据库数据目录 #…...

赎金信00

题目链接 赎金信 题目描述 注意点 magazine中的每个字符只能在ransomNote中使用一次ransomNote和magazine由小写英文字母组成 解答思路 因为ransomNote和magazine由小写英文字母组成&#xff0c;所以使用大小为26的数组存储magazine中a~z对应出现的次数&#xff0c;ransom…...

如何运行github上的项目

为了讲明白这个过程&#xff0c;特意做了一个相当来说比较好读懂的原理图&#xff0c;希望和我一样初学的小伙伴也能很快上手哈&#x1f60a; 在Github中找到想要部署的项目&#xff0c;这里以BartoszJarocki/CV&#xff08;线上简历&#x1f4c4;&#xff09;项目为例 先从头…...

机器学习-02-机器学习算法分类以及在各行各业的应用

总结 本系列是机器学习课程的第02篇&#xff0c;主要介绍机器学习算法分类以及在各行各业的应用 本门课程的目标 完成一个特定行业的算法应用全过程&#xff1a; 定义问题&#xff08;Problem Definition&#xff09; -> 数据收集(Data Collection) -> 数据分割(Data…...

Java项目学习

一、Java项目学习 1.1 瑞吉外卖(项目提供的资料没笔记) 视频资源&#xff1a;https://www.bilibili.com/video/BV13a411q753/?p1 本人git项目地址&#xff1a;https://gitee.com/xx-xuxin/reggie_take_out.git 瑞吉外卖Day01~Day06没讲的功能&#xff08;全功能实现&#xf…...

npm run dev和npm run serve两个命令的区别

npm run dev和npm run serve两个命令的区别 前端开发过程中运行Vue项目的时候&#xff0c;有时候使用npm run serve命令可以启动项目&#xff0c;有时候却会报错&#xff1b;有时候使用npm run dev命令可以启动项目&#xff0c;有时候却也会报错。是什么原因造成这种情况呢&am…...

ui设计:利用即使设计设计出漂亮样式

目录 一、基本操作 二、具体介绍 6-1 填充图片 6-2 填充色 6-3 图标 右边栏基础设置 右边栏导出​编辑 一、基本操作 二、具体介绍 6-1 填充图片 选择其一图片填充 6-2 填充色 6-3 图标 右边栏基础设置 右边栏导出...

[unity]lua热更新——个人复习笔记【侵删/有不足之处欢迎斧正】

一、AssetBundle AB包是特定于平台的资产压缩包&#xff0c;类似于压缩文件 相对于RESOURCES下的资源&#xff0c;AB包更加灵活轻量化&#xff0c;用于减小包体大小和热更新 可以在unity2019环境中直接下载Asset Bundle Browser 可以在其中设置关联 AB包生成的文件 AB包文件…...

Springboot日常总结-@RestController和@Controller的区别

RestController和 Controlle是两种不同的控制器实现&#xff0c;它们的主要区别在于如何处理返回的数据和是否支持跳转到视图页面。 Controller 是一个基本的控制器注解&#xff0c;它允许你将一个类标记为一个Spring MVC控制器处理器。使用 Controller 的类中的方法可以直接返…...

MongoDB之客户端工具与核心概念及基本类型篇

MongoDB之客户端工具与核心概念及基本类型篇 文章目录 MongoDB之客户端工具与核心概念及基本类型篇1. MongoDB是什么?1. 关于MongoDB2. 相关客户端工具1. MongoDB Compass2. Studio 3T3. Navicat for MongoDB4. NoSQL Manager for MongoDB Professional 2.MongoDB相关概念2.1 …...

Essential C++ 编程基础

Essential C 前言1.1 如何撰写 C程序1.2 对象的定义与初始化1.3 撰写表达式1.4 条件语句和循环语句1.5 如何运用Array和Vector1.6 指针带来弹性1.7 文件的读写 前言 通过Essential C笔记的形式对C相关重点知识进行汇总&#xff0c;读者通读此系列文章就可以轻松的把该语言基础捡…...

Dify v0.9+审计日志配置避坑清单:7类常见错误配置导致ISO 27001认证失败(附校验脚本)

第一章&#xff1a;Dify v0.9审计日志配置的核心价值与合规基线审计日志是 Dify 平台安全治理与合规落地的关键基础设施。自 v0.9 版本起&#xff0c;Dify 引入了基于事件驱动的细粒度审计日志框架&#xff0c;覆盖应用创建、提示词变更、数据集更新、模型调用、权限分配等全生…...

靠谱的安卓安全加固公司怎么选?从价格、案例到合同避坑的完整指南

当你准备为公司核心的App采购安全加固服务时&#xff0c;意味着你已经进入了“货比三家”的决策阶段。你不再满足于看宣传册&#xff0c;而是开始关心&#xff1a;这家公司报价多少&#xff1f;案例是否真实&#xff1f;合同里有没有隐藏条款&#xff1f;售后响应速度究竟如何&…...

超越Agent:当服务器不让装软件时,用Zabbix SNMP监控的3种高阶玩法与模板优化

超越Agent&#xff1a;Zabbix SNMP监控在受限环境下的高阶实践 想象一下这样的场景&#xff1a;凌晨三点&#xff0c;你被告警电话惊醒&#xff0c;一台关键业务服务器出现性能问题。但当你准备登录排查时&#xff0c;却发现这台服务器严格禁止安装任何监控Agent——这是许多运…...

终极Align-Anything训练指南:从SFT到PPO的完整多模态对齐流程详解

终极Align-Anything训练指南&#xff1a;从SFT到PPO的完整多模态对齐流程详解 【免费下载链接】align-anything Align Anything: Training All-modality Model with Feedback 项目地址: https://gitcode.com/gh_mirrors/al/align-anything Align-Anything是一个强大的开…...

别再瞎猜了!JDK 17下ShardingSphere + MyBatis报错‘module java.base does not opens’的根治方案

JDK 17环境下ShardingSphere与MyBatis深度整合的模块化难题与根治方案 最近在将一个基于Spring Boot的生产级应用从JDK 11升级到JDK 17时&#xff0c;遇到了一个令人头疼的问题&#xff1a;系统在启动时一切正常&#xff0c;但在执行MyBatis查询时却突然抛出java.lang.reflect.…...

告别屏幕偏色!手把手教你用高通QDCM 6.0 + CA-410校准手机显示(附完整避坑清单)

告别屏幕偏色&#xff01;手把手教你用高通QDCM 6.0 CA-410校准手机显示&#xff08;附完整避坑清单&#xff09; 你是否曾经遇到过这样的困扰&#xff1a;同一张照片在不同设备上显示效果天差地别&#xff1f;作为一名硬件开发者或显示技术爱好者&#xff0c;精准的色彩还原能…...

LyricsX终极指南:macOS上最强大的歌词同步工具

LyricsX终极指南&#xff1a;macOS上最强大的歌词同步工具 【免费下载链接】LyricsX &#x1f3b6; Ultimate lyrics app for macOS. 项目地址: https://gitcode.com/gh_mirrors/ly/LyricsX LyricsX是macOS平台上最专业的歌词同步软件&#xff0c;能够智能识别当前播放的…...

PyQt5-tools安装总失败?可能是你的Python版本和系统环境在‘打架’(附兼容性自查清单)

PyQt5-tools安装失败深度排查&#xff1a;环境兼容性全景解决方案 当你在终端看到那个刺眼的红色报错——"Could not find a version that satisfies the requirement pyqt5-tools"时&#xff0c;可能已经尝试了更换镜像源、添加信任主机参数等常规操作。但问题依旧存…...

高性能开源PLC编程平台:OpenPLC Editor工业自动化开发完整解决方案

高性能开源PLC编程平台&#xff1a;OpenPLC Editor工业自动化开发完整解决方案 【免费下载链接】OpenPLC_Editor 项目地址: https://gitcode.com/gh_mirrors/ope/OpenPLC_Editor OpenPLC Editor作为一款基于PLCopen国际标准的开源工业自动化编程平台&#xff0c;为工业…...

Phi-3-mini模拟电路设计助手:Multisim仿真分析与报告生成

Phi-3-mini模拟电路设计助手&#xff1a;Multisim仿真分析与报告生成 1. 引言&#xff1a;电子工程师的智能设计伙伴 在电子工程实验室里&#xff0c;经常能看到这样的场景&#xff1a;学生盯着Multisim仿真波形图眉头紧锁&#xff0c;工程师反复调整电路参数却得不到理想效果…...