ImageIO并发情况下内存溢出问题(jdk1.7以下)

来源:互联网 发布:淘宝网页版登陆首页 编辑:程序博客网 时间:2024/06/05 09:25
这几天在查一个内存溢出的问题,虽然不能确定到底是不是溢出了,但是jvm占的内存却会疯狂增长,当然是在没有设置 -Xmx 的前提下。

问题主题代码以被抽出,构成测试用例如下:
import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import javax.imageio.ImageIO;public class ImageIOTest {public static void main(String[] args) throws Exception {int nums = 800;//for (int i = 0; i < nums; i++) {// new Thread(new Tt1()).run(); //单线程//}new Thread(new DoMutil(30, nums)).run(); // 并发Thread.sleep(1000000);}}class DoMutil implements Runnable {int threadNum = 1;int nums = 1;public DoMutil(int threadNum, int nums) {this.threadNum = threadNum;this.nums = nums;}@Overridepublic void run() {ExecutorService executorService = Executors.newFixedThreadPool(threadNum);for (int i = 0; i < nums; i++) {executorService.execute(new Tt1());}}}class Tt1 implements Runnable {static String xx = "d:/x/xxx.png";public void run() {try {BufferedImage image = ImageIO.read(new File(xx));image.flush();int width = image.getWidth();Thread.sleep(100);} catch (IOException e1) {} catch (InterruptedException e) {}}}
运行条件:1.  放个图片在 d:/x/xxx.png 。我的图片大小为600多k。

运行结果(win7 64位 jdk1.7.0_17): 1.单线程运行时,内存使用正常。 2. 30个并发执行时,内存使用近1G。
虽然这个1G的被jvm占用的内存,并非“使用的堆”大小,而是“堆”大小,但是机器的内存确实被用掉,影响了其他的系统。

经过各种分析。。。jvisualvm。。。gc日志。。。。均为发现任何问题。
-----------------------------------------------华丽分割--------------------------苦逼寻找-----------------------------------------

昨日,有人在办公群里问newWorkStealingPool 和newCachedThreadPool的区别,遂下载jdk1.8,把Executors源码给扫了,解释之。。
------------------------------转折点 如上-------------------------------

今日继续做测试,执行上述程序,无意间发现内存不再被使用这么多了,而是正常的270M左右。 
疑惑不解~ 
突然发现了这个


我X。。。jdk1.8.。。。

于是,又进行了多次测试,果然,jdk8是正常的,jdk7就是会吃掉很大内存。

-----------------------------结尾----------------------------
至此,基本上找到了根源。。。估计jdk7中,关于imageIO在线程池中并发使用时,会出现一些问题。当然了,问题就不深究了。
咱也没看过jvm源码。。。

PS: 这个问题,还没最终解决,因为还没上线到linux生产环境中,但是,这块应该还是存在问题的,所以,遇到该问题的小伙伴,可以参考下哈~哈哈
0 0