线上系统/tmp 目录不断增长分析与总结
1、问题描述
系统配置为单核4G, web 工程配置堆2G, /tmp目录 二进制文件不断增加,平均一天增加20G, 手动清理/tmp目录,重启系统,问题依旧。
2、分析
2.lsof -p pid 确定tmp文件都被进程id为10791的同一个Java进程打开。
根据上面的分析,这些文件应该是该进程的临时文件,而且不断在增加,有可能是文件句柄泄露。
查看该进程的句柄图
12.15号,系统打开的句柄数量在逐步的增加,而且没有出现相对平稳的迹象,确定是句柄泄露了,这印证了我们的猜想。
下来需要进一步分析究竟是什么原因造成的句柄泄露。
谷歌搜索关键字,确定FlateDecode是解码 PDF stream 的一个工具。查看程序中引用相关pdf的代码,如下图所示:
public static byte[] transfer(byte[] bytes, int pageNum) throws IOException { LOG.info("PDF合同转IMAGE开始...pageNum={}", pageNum); PdfDecoder decode_pdf = new PdfDecoder(true); decode_pdf.scaling = 1.5F; FontMappings.setFontReplacements(); byte[] outbytes = new byte[0]; ByteArrayOutputStream out = new ByteArrayOutputStream(); try { decode_pdf.openPdfArray(bytes); //bytes is byte[] array with PDF BufferedImage img = decode_pdf.getPageAsImage(pageNum); ImageIO.write(img, "jpg", out); outbytes = out.toByteArray(); LOG.info("PDF合同转IMAGE成功...pageNum={}", pageNum); } catch (Exception e) { LOG.error("PDF合同转IMAGE异常...pageNum={},e={}", pageNum, e); } finally { out.close(); } return outbytes;} |
这段代码用来将pdf转化成一个jpg的图片,使用了jpedal第三方库。
jpedal是一个开源的纯Java的PDF文档解析库,可以用来方便的查看和编辑文字和图片。
回到代码, 按照以往编码的经验,有可能是PdfDecoder没有释放资源,导致生成的临时文件一直没有释放掉。查看jpedal文档,发现的确提供了closePdfFile 关闭pdf文件的方法。
finally 块里添加
decode_pdf.flushObjectValues(true);
decode_pdf.closePdfFile();
重新发版,发现之后句柄图达到了相对平稳的状态,tmp目录也不再继续增加临时文件。
虽然问题解决了,但是还有一些困惑。临时文件怎么生成的?page fault为啥这么多?
1、临时文件到底是怎么生成的?
decode_pdf.openPdfArray(bytes) 根据传进来的字节流 打开pdf文件,

jpedal在这里做了一个优化,当pdf文件小于16k时或者alwaysCacheInMemory = -1时,直接内存缓存该pdf。
当pdf文件的大小大于16k时,会在临时目录下生成一个前缀为page,后缀为bin的二进制文件,该临时目录由系统参数 java.io.tmpdir 指定,默认在/tmp目录下。
这样,由于线上环境的pdf基本都大于16k,所以/tmp目录下就会看到不断的临时文件生成。这个临时文件命名规则为page***.bin。
2、添加closePdf文件之后,为啥问题就解决了呢?
closePdf会调用PdfReader的closePdfFile()方法,该方法根据缓存的临时文件名称删除该临时文件。

3、未关闭pdf文件,为啥会引起较多的page fault呢?
page fault 分为 minor page fault 和major page fault。
major page fault也称为hard page fault, 指需要访问的内存不在虚拟地址空间,也不在物理内存中,需要从慢速设备载入。从swap回到物理内存也是hard page fault。
minor page fault也称为soft page fault, 指需要访问的内存不在虚拟地址空间,但是在物理内存中,只需要MMU建立物理内存和虚拟地址空间的映射关系即可。
(通常是多个进程访问同一个共享内存中的数据,可能某些进程还没有建立起映射关系,所以访问时会出现soft page fault)
正常情况下,系统也会有一些pagefault,如下图所示:

,所以pagefault和该问题没有直接关系。minflt表示从内存加载数据时每秒出现的小的错误数目,可以忽略。如果majflt较大,表示从磁盘载入内存页面,发生了swap,此时需要关注。
3、总结
我们详细的回顾了此次线上发生的问题,以及如何去定位,然后去解决问题的整个过程。
(1)问题发现,收到系统磁盘空间不足的报警。
(2)问题定位,先根据du确认是tmp目录增长过快的问题,然后根据lsof和进程句柄图确定是文件句柄泄露,再根据临时文件的文件内容,定位相关的源代码,查看源代码,确认是文件句柄资源没有正确释放。
(3)解决问题,查看api,确认是资源泄露的问题,修复代码上线。
线上系统/tmp 目录不断增长分析与总结的更多相关文章
- CentOS系统/tmp目录里面的文件默认保留多久
一.CentOS系统/tmp目录里面的文件默认保留多久 CentOS6默认保留30天,CentOS7默认保留10天 一.CentOS7系统/tmp目录里面的文件默认保留多久 CentOS7默认保留10 ...
- 线上BUG:MySQL死锁分析实战
原文链接:线上BUG:MySQL死锁分析实战 1 线上告警 我们不需要关注截图中得其他信息,只要能看到打印得org.springframework.dao.DeadlockLoserDataAcces ...
- 有关线上系统点击没有任何相应得问题思考,主要针对PC端应用程序
1.问题得起因 前段时间,客户得某些机器上,点击应用系统得快捷方式,没有任何响应,不弹出程序主界面,也没有任何得报错提示,甚至程序得错误日志也没有任何输出. 当时,听说发生这种情况得时候,有点懵了,不 ...
- 线上redis服务内存异常分析。
项目中,新增了一个统计功能,用来统计不同手机型号的每天访问pv,看了下redis2.6有个setbit的功能,于是打算尝尝鲜把 redis从2.4更新到了2.6 因为是租了vps.服务器的内存只有4g ...
- Linux线上系统程序debug思路及方法
http://blog.csdn.net/wangzuxi/article/details/44766221
- HBase工程师线上工作经验总结----HBase常见问题及分析
阅读本文可以带着下面问题:1.HBase遇到问题,可以从几方面解决问题?2.HBase个别请求为什么很慢?你认为是什么原因?3.客户端读写请求为什么大量出错?该从哪方面来分析?4.大量服务端excep ...
- (转)HBase工程师线上工作经验总结----HBase常见问题及分析
阅读本文可以带着下面问题:1.HBase遇到问题,可以从几方面解决问题?2.HBase个别请求为什么很慢?你认为是什么原因?3.客户端读写请求为什么大量出错?该从哪方面来分析?4.大量服务端excep ...
- 排查Java线上服务故障的方法和实例分析
前言 作为在线系统负责人或者是一个技术专家,你可能刚刚接手一个项目就需要处理紧急故障,或者被要求帮忙处理一些紧急的故障,这个时候的情景是: (1)你可能对这个业务仅仅是听说过,而不怎么真正了解: (2 ...
- erlang 线上分析工具集锦
1.Recon-Erlang线上系统诊断工具(引自): Erlang系统素以稳定可靠闻名,但是它也是c实现的,也是要管理比如内存,锁等等复杂的事情,也会出现Crash,而且crash的时候大部分原因是 ...
随机推荐
- svn搭建服务器--- 绝对好使---杜恩德
如何创建 SVN 服务器,并搭建自己的 SVN 仓库 听语音 | 浏览:1289 | 更新:2016-09-10 17:45 1 2 3 4 5 6 7 分步阅读 百度经验:jingyan.baidu ...
- Swift 3.0在集合类数据结构上的一些新变化
一.Array数组的更改 array数组中修改的API示例如下: //创建大量相同元素的数组//创建有10个String类型元素的数组,并且每个元素都为字符串"Hello"//sw ...
- Object.assign()
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign 说明 Ob ...
- web.xml文件--编码注意事项
写在前面: 最近发布项目的时候,要修改web.xml文件的内容,然后我在本机的web.xml文件中是有注释的,但是到了服务器上面,就说编码不同.我也没有怎么注意.就继续启动服务器,但是访问网站,一直报 ...
- java并发编程的艺术——第五章总结(Lock锁与队列同步器)
Lock锁 锁是用来控制多个线程访问共享资源的方式. 一般来说一个锁可以防止多个线程同时访问共享资源(但有些锁可以允许多个线程访问共享资源,如读写锁). 在Lock接口出现前,java使用synchr ...
- 4.前端基于react,后端基于.net core2.0的开发之路(4) 前端打包,编译,路由,模型,服务
1.简要的介绍 学习react,首先学习的就是javascript,然后ES6,接着是jsx,通常来说如果有javascript的基础,上手非常快,但是真正要搭建一个前端工程化项目,还是有很多坑的 搞 ...
- 【NOIP模拟】从我背后出现
Description 给定n个点m条边的无向连通图,对于每条边求出强制选这条边后的最⼩⽣成树⼤⼩. \(n\leq 10^5,m\leq 2*10^5\) Input Format 第 1 行包含两 ...
- java中的参数传递是按引用传递还是按值传递
最近去面试,有一个面试官问到java中参数传递的问题,感觉自己对于这一块还是理解的不够深.今天我们就一起来学习一下Java中的接口和抽象类.下面是本文的目录大纲: 一 . 什么是按值传递,什么是按引用 ...
- [置顶]
MVC输出缓存(OutputCache参数详解)
1.学习之前你应该知道这些 几乎每个项目都会用到缓存,这是必然的.以前在学校时做的网站基本上的一个标准就是1.搞定增删改查2.页面做的不要太差3.能运行(ps真的有这种情况,答辩验收的时候几个人在讲台 ...
- Gulp-静态网页模块化
前言: 在做纯静态页面开发的过程中,难免会遇到一些的尴尬问题.比如:整套代码有50个页面,其中有40个页面顶部和底部模块相同.那么同样的两段代码我们复制了40遍(最难受的方法).然后,这个问题就这样解 ...