线上系统/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的时候大部分原因是 ...
随机推荐
- Shell编程实践之批量安装JDK
实验环境 只有两台机子,一台虚拟机192.168.1.200,另外一台物理机192.168.1.201. 目标 执行一个shell脚本,给这两台机子自动安装jdk. 实验步骤 1.自动设置ssh免密码 ...
- mysql版本升级
环境 mysql安装在centos上,需要升级. mysql的版本是 mysql> select version(); +-----------+ | version() | +-------- ...
- 小型Web页打包优化(下)
之前我们推送了一篇小型Web项目打包优化文章,(链接),我们使用了一段时间, 在这过程中我们也一直在思考, 怎么能把结构做的更好.于是我们改造了一版, 把可以改进的地方和可能会出现的问题, 在这一版中 ...
- iOS cocos2d游戏引擎的了解之一
ios游戏引擎之Cocos2d(一) cocos2d是一个免费开源的ios游戏开发引擎,并且完全采用object-c进行编写,这对于已经用惯object-c进行ios应用开发的童鞋来说非常容易上手.这 ...
- JAVA多线程统计日志计数时的线程安全及效率问题
最近工作上遇到一个需求:需要根据nginx日志去统计每个域名的qps(Query Per Second,每秒查询率)数据. 解决了日志读取等问题之后,为了写一个尽可能高效的统计模块,我决定用多线程去计 ...
- linux集群批量执行命令
因为工作需要,需要修改集群中机器的配置,一台一台的修改太浪费时间,就想能不能通过自动化脚本批量执行命令,尝试写一个,自己shell不熟悉,写的有点渣渣 if [ "$#" -ne ...
- 653. Two Sum IV - Input is a BST
Given a Binary Search Tree and a target number, return true if there exist two elements in the BST s ...
- Cat 跨线程之 ForkedTransaction 用法和原理分析
代码 package com.dianping.cat.message.internal; import com.dianping.cat.Cat; import com.dianping.cat.m ...
- 改造 Combo Select支持服务器端模糊搜索
项目中使用了 combo select,为缺省的select增加模糊搜索的功能,一直运行得很好. 1 碰到的问题 但最近碰到一个大数据量的select:初始化加载的数据项有2000多个.我们采用 ...
- 关于文件上传的ajax交互
首先我们来了解一下上传文件 <input type="file"> input的file常用上传类型 后缀名 MIME名称 *.3gpp audio/3gpp, vid ...