今天做一个测试,测试InputStream未关闭资源是否会造成内存泄漏
一 测试程序准备
未关闭InputStream的Java程序【UrlStreamNoClose.java】:
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
public class UrlStreamNoClose {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10000000; i++) {
System.out.println("加载次数:" + i);
InputStream is = new URL("jar:file:/Users/bingsanfang/Desktop/jrt-fs.jar!/META-INF/MANIFEST.MF").openStream();
}
}
}
关闭InputStream的程序【UrlStreamClose.java】:
mport java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
public class UrlStreamClose {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10000000; i++) {
System.out.println("加载次数:" + i);
try(InputStream is = new URL("jar:file:/Users/bingsanlang/Desktop/jrt-fs.jar!/META-INF/MANIFEST.MF").openStream()){
System.out.println("enter" + i);
}
}
}
}
对以上两个程序分别执行打包程序打成可执行jar包,以第一个程序为例,执行打包的流程如下:
javac UrlStreamNoClose.java
jar -cvf UrlStreamNoClose.jar UrlStreamNoClose.class
打包完成后,需要修改Meta信息,否则会报错:无执行清单
vim UrlStreamNoClose.jar
选择META-INF/MANIFEST.MF进行修改,添加第三行的内容,注意:后面有个空格。
添加完成后就可以执行了。
二、测试
2.1 内存泄漏测试:未关闭close
执行 如下命令,观察这个进程使用的内存大小:
java -jar UrlStreamNoClose.jar
可以看到一直输出,通过监控可以看到内存使用一直上涨,上涨到5G了:
这时候可以执行jps查看进程ip,然后 执行kill杀掉进程:
192:/ bingsanlang$ jps
10933 Jps
10908 jar
192:/ bingsanlang$ kill -9 10908
2.2 关闭close,未产生内存泄漏
执行 如下命令,观察这个进程使用的内存大小:
java -jar UrlStreamClose.jar
可以看到一直输出,通过监控可以看到内存使用一直平稳,只有800多M:
三、结论
使用URL.openStream 应主动关闭,否则容易造成内存泄漏,try可以实现关闭资源的能力,关闭的代码执行路径如下: