首页 > 系统相关 >java 关于 Finalizer 过多导致内存(Res)缓慢上涨

java 关于 Finalizer 过多导致内存(Res)缓慢上涨

时间:2023-11-24 16:58:40浏览次数:50  
标签:bin java finalize Res Finalizer BufferedReader 内存 关闭

 

病因: 事情的起因是由Flume的项目采集问题引发的. 测试人员发现用top命令查看采集进程的Res一直不断上涨姿势. 所以怀疑是内存泄漏.

 

 

一, 对症下药
首先, 第一步肯定是先瞅瞅代码, 看看有没有那些资源啥的没关闭, 正如读者所想 ---- 没有发现.

二, 通过辅助工具
最简单查看java内存的方法就是分析dump文件.

1> 查找当前进程的Pid , 如图所示, pid 是 50480

2> 到jdk安装目录bin下面找一个 jmap的命令

3> 然后 ./jmap -dump:format=b,file=/opt/heap/heap1.bin 50480 , 得到 第一个 heap1.bin

4> 过个把小时, 再使用这个命令 ./jmap -dump:format=b,file=/opt/heap/heap2.bin 50480 , 得到第二个heap2.bin

5> 然后就是分析环节了, 我使用的是Eclipse的MAT插件, 具体安装过程百度之

6> 用Eclipse 分别打开heap文件, 此时请看配图

 

 

 

当我们把两个, 都点击 Histogram 的时候, 会出现如下界面:

 

根据图中所示, 选择对比两个堆文件变量的生成情况, 然后会得到下图:

 

快看快看, 就是这龟儿子导致了我们的内存一路飙升, 此时的你应该能想到哪些地方使用到了FileInputStream了. 对, 没错, 就去那个地方找. 如果你对代码不熟悉的话, 也可以参照下面方法来定位位置:

 

 

(1) 如图, 我们再次点击这个, 然后得到变量生成表单.

 

 

(2) 在对象表单中寻找到我们刚刚看到的龟儿子FiliInputStream, 然后右击选择List Objects, 然后选择 outGoing...

 

 

(3) 然后你就可以看到这个FileInputStream到底是什么了, 这时候去代码那边找原因.

7> 由于涉及到代码保密协议, 我就用测试代码替代源代码, 大致逻辑如下

 

 

表面上看, 这段代码没什么大问题, 因为我的reader是需要在其他地方使用, 所以会在使用完之后关闭这个BufferedReader流. 然后嵌套的流也会相应的关闭. 没毛病啊.

也许这是所有程序猿公认的, BufferedReader 流关闭, 嵌套的流也会相应的关闭. 这句话没有错. 但是, 在高速度和高并发的情况下, 对于流的关闭就会有问题.

因为 如果没有显式关闭流, jvm会有一个finalize()的方法来做最后的防线, 也就是说我们BufferedReader流虽然关闭了, 但是嵌套的流不关闭的话, 只能通过finalize()方法来关闭.

但是在高并发情况下, 也许FileInputStream流开的很多, 但是finalize() 是单线程操作的(具体内部原理请百度之).finalize()方法会把需要释放的资源放到一个Queue中, 如果释放的动作慢于产生的速度, 这时就会有大量的Finalizer堆积, 导致内存的异常.

所以, 建议在高并发, 高速度的条件下, 尽量别使用嵌套的BufferedReader流. 改用下面:

 

 

通过反复测试, 没有出现Finalizer 大量堆积的情况, 异常解除.

由于本人是菜鸟一枚, 文中不免会出现这样那样的错误, 望大佬们提出宝贵建议, 十分感谢.
————————————————
版权声明:本文为CSDN博主「Hello法克」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41771503/article/details/79789086

 

标签:bin,java,finalize,Res,Finalizer,BufferedReader,内存,关闭
From: https://www.cnblogs.com/softidea/p/17854110.html

相关文章

  • 这篇保证你彻底搞懂Java NIO的Selector事件选择器
     Selector提供选择执行已经就绪的任务的能力,使得多元I/O成为可能,就绪选择和多元执行使得单线程能够有效率地同时管理多个I/Ochannel。C/C++许多年前就已经有select()和poll()这两个POSIX(可移植性操作系统接口)系统调用可供使用。许多os也提供相似的功能,但对Java程序......
  • Java实验报告五
    实验五实验名称:文件与I/O流实验目的:掌握文件与输入输出流的使用。实验时间:(2学时)实验类型:验证型实验内容:1.创建类:FindFile.java,遍历当前目录,打印目录中文件名称,目录打印”isDirectory”,文件打印“isfile”。修改程序打印当前目录及子目录信息。提示:当前目录名用......
  • JavaWeb中的文件的上传和下载
    文件上传1.要有一个form标签,method=post请求2.form标签的encType属性的值必须为multipart/form-data值3.在from标签中使用inputtype=file添加上传的文件4.编写服务器代码接收上传的数据Content-Type:表示提交的数据类型enctype="multipart/form-data":表示提交的数据,以多段(每......
  • Java线程生命周期
    操作系统线程生命周期操作系统线程生命状态有5种。初始状态(New)进程正在被创建时的状态。仅为线程对象开辟了一块堆内存,实际上线程在操作系统层面还未创建。就绪状态(Ready)可运行,由于其他进程处于运行状态而暂时停止运行运行状态(Running)该进程此时正占用CPU......
  • Java实验报告
    实验一实验名称:JAVA中循环结构实验目的:熟悉循环结构,熟悉JAVA类的定义以及参数的传递。实验时间:(2学时)实验类型:验证型实验内容:(1)金字塔:Pyramid.java在屏幕上显示一个由星型符号“*”组成的金字塔图案,要求用户设置金字塔的高度,程序能根据用户设置的高度打印金字塔,......
  • Java系列之 String indexOf() 方法
    我|在这里 ......
  • General error: 1205 Lock wait timeout exceeded; try restarting transaction【事务
    转载:https://blog.51cto.com/u_12390904/6254246       ......
  • 03_Exception in thread “main“ java.lang.AssertionError
    问题maven构建报错***[INFO]---maven-compiler-plugin:3.8.1:compile(default-compile)@engine_auth---[INFO]Changesdetected-recompilingthemodule![INFO]Compiling38sourcefilestoC:\Users\...\target\classes[INFO]-----------------------------......
  • [Java] 解析Xml配置文件
    1、解析方法importjavax.xml.parsers.DocumentBuilder;importjavax.xml.parsers.DocumentBuilderFactory;importorg.w3c.dom.Document;importorg.w3c.dom.NamedNodeMap;importorg.w3c.dom.Node;importorg.w3c.dom.NodeList;publicstaticMap<String,String>pars......
  • postgresql从入门到精通 - 第35讲:中间件PgBouncer部署|PostgreSQL教程
     PostgreSQL从小白到专家,是从入门逐渐能力提升的一个系列教程,内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容,希望对热爱PG、学习PG的同学们有帮助,欢迎持续关注CUUGPG技术大讲堂。 第35讲:中间件PgBouncer部署11月25日(周六)19:30-20:30,往期......