添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

未关闭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可以实现关闭资源的能力,关闭的代码执行路径如下:

下面的方法是从aws s3 读取文件对象下载到本地 public int downloadFile(HttpServletResponse httpResponse, String storePath, long p, long pend, int len, long realLen) throws IOException { String key = getKeyByStorePath... FileInputStream 在最后通过open(name) 这个方法打开文件,open()调用open0(), open0()是一个native方法,实现不是java,看到注释,大概的意思就是指定文件路径,然后可以打开进行读操作。那反射要实现,需要获取哪个方法呢?注意这里是FileInputStream,是一个字节流不要出现中文字符否则乱码。既然知道open() 方法,那就可以用反射了,注意这个方法是private。很明显看到这个第二次的输出是没有任何结果的。Java的反射是个什么东西? 前言 现象:生产环境java项目,运行一周后出现OOM问题,初步排查是内存泄漏问题导致OOM。 在讨论内存泄漏问题之前,我们首先看一下对内存泄漏的定义,在维基百科上,对内存泄漏问题的定义如下:内存泄漏(Memory leak)是在计算机科学中,由于疏忽或错误造成程序能释放已经不再使用的内存。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了... 使用InputStream文件流之后一定要关闭它,否则在使用某些操作的时候发生异常。比如说如下代码: File file = new File(“C://test.txt"); InputStream is = new FileInputStream(file); file.delete(); 上面的代码没有关闭文件流,虽然执行了file.delete() 先给出本文的重点:这里所谓的资源(resource)是指在程序完成后,必须关闭的对象, try-with-resources 语句确保了每个资源在语句结束时关闭;使用 Java 7 新增的 try-with-resources 语句 代替 try-finally 语句进行资源关闭,不仅代码更精简而且更安全;支持 try-with-resources 语句 的类必须都实现 AutoCloseable... 最近接触了一些面试者,在面试过程中有涉及到内存泄露的问题,其中有不少人回答说,如果文件打开后,没有关闭导致内存泄露。当被继续追问,为什么导致内存泄露时,大部分人都没有回答出来。 本文将具体讲一讲 文件(流)关闭与内存泄露的关系。 什么是内存泄露 定义:当生命周期长的实例L 不合理地持有一个生命周期短的实例S,导致S实例无法被正常回收 最近因为一个项目需求,需要支持上传文件,并且在上传的过程中通过流式的方式生成md5校验码,然后好需要利用这个输入流来生成本地预览文件,而InputStrream是只能读一次的,并不能重复读,所以在这里就需要进行流的复制。 解释一下,fileUpload是自定义的文件Model实体。 // 生产文件md5校验码,并且复制fileUpload.getInputStream(),否则input... 曾几何时,作为java程序员要记住的一条准则就是,流用完了一定要在关闭,一定要写在`finally`里。finally {out.flush(); out.close();}但是最近发现一个stream是不需要关闭的。它就是ByteArrayOutputStream,当然还有它的妹妹ByteArrayInputStream和表哥StringWriter。道理一样,我们就不讨论亲戚们了。作为一种Ou...