commons-io引起的ygc问题

今天接到任务,图片上传服务器的性能有问题,高峰期间YGC频率在2秒一次,维护应用的程序员诊断的原因是图片处理API有性能问题。
不管咋样,亲自看一把才是王道,jmap -dump出堆内存文件。
用Eclipse MAT打开一看,发现FileCleaningTracker这个对象占用了将近一半的堆内存。
查看了下代码,发现这个类是commons-io下用于追踪文件的一个方法引起的问题。方法如下:
/**
* Track the specified file, using the provided marker, deleting the file
* when the marker instance is garbage collected.
* The speified deletion strategy is used.
*
* @param path the full path to the file to be tracked, not null
* @param marker the marker object used to track the file, not null
* @param deleteStrategy the strategy to delete the file, null means normal
* @throws NullPointerException if the path is null
*/
public void track(String path, Object marker, FileDeleteStrategy deleteStrategy) {
if (path == null) {
throw new NullPointerException("The path must not be null");
}
addTracker(path, marker, deleteStrategy);
}


/**
* Adds a tracker to the list of trackers.
*
* @param path the full path to the file to be tracked, not null
* @param marker the marker object used to track the file, not null
* @param deleteStrategy the strategy to delete the file, null means normal
*/
private synchronized void addTracker(String path, Object marker, FileDeleteStrategy deleteStrategy) {
// synchronized block protects reaper
if (exitWhenFinished) {
throw new IllegalStateException("No new trackers can be added once exitWhenFinished() is called");
}
if (reaper == null) {
reaper = new Reaper();
reaper.start();
}
trackers.add(new Tracker(path, deleteStrategy, marker, q));
}


发现每当创建文件的时候该方法都会创建一个Reaper线程,代码如下:
/**
* Run the reaper thread that will delete files as their associated
* marker objects are reclaimed by the garbage collector.
*/
@Override
public void run() {
// thread exits when exitWhenFinished is true and there are no more tracked objects
while (exitWhenFinished == false || trackers.size() > 0) {
try {
// Wait for a tracker to remove.
Tracker tracker = (Tracker) q.remove(); // cannot return null
trackers.remove(tracker);
if (!tracker.delete()) {
deleteFailures.add(tracker.getPath());
}
tracker.clear();
} catch (InterruptedException e) {
continue;
}
}
}
}

只有当主线程手动调用exitWhenFinished方法的时候,这些Reaper线程才会进行清理动作。这样在图片上传高峰期将会在内存中积累很大的垃圾数据。

解决方案:
创建临时文件之后不调用该方法,写脚本事后进行删除工作。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值