美文网首页
内存泄漏之未关闭文件流

内存泄漏之未关闭文件流

作者: WilsonMing | 来源:发表于2023-06-29 11:22 被阅读0次

如果Android开启严格模式情况下会监控APP是否存在未关闭文件流,如果监控到存在未关闭文件流情况会报以下错误:

A resource was acquired at attached stack trace but never released. 
See java.io.Closeable for information on avoiding resource leaks.
                                                                
java.lang.Throwable: Explicit termination method 'close' not called
                                                                    
at dalvik.system.CloseGuard.open(CloseGuard.java:180)
                                                                
at java.io.FileInputStream.<init>(FileInputStream.java:147)

出现这种情况基本是流对象如FileInputStream没有调用close(),或者try{}catch{},没有调用finally()

对于这种问题有三种解决方案:

  1. Java 7 之后,可以使用try-with-resource方式处理
  2. Java最基础的手动关闭的形式try-catch-finally
  3. Kotlin使用use函数

使用try-with-resource方式

Java 7 之后,可以使用try-with-resource方式处理,示例代码如下

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

// 自定义类实现AutoCloseable接口
public class MyFileInputStream extends FileInputStream implements AutoCloseable {

    public MyFileInputStream(File file) throws IOException {
        super(file);
    }

    @Override
    public void close() throws IOException {
        // 重写close方法
        System.out.println("Closing MyFileInputStream");
        super.close();
    }
}

public class Test {

    public static void main(String[] args) {
        // 使用try-with-resources语句自动关闭资源
        try (MyFileInputStream fis = new MyFileInputStream(new File("test.txt"))) {
            // 在try块中使用资源
            int data = fis.read();
            while (data != -1) {
                System.out.print((char) data);
                data = fis.read();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

try-catch-finally

使用Java最基础的手动关闭的形式try-catch-finally,示例代码:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public void saveFile(boolean externalStorage) {
    String s = "12345";
    File file;
    FileOutputStream fos = null;
    try {
        file = externalStorage ? new File(getExternalFilesDir(null), "log") : new File(getFilesDir(), "log");
        fos = new FileOutputStream(file);
        fos.write(s.getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 关闭文件流
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

使用use函数

use函数是kotlin标准库中的一个扩展函数,它可以用于自动关闭实现了CloseableAutoCloseable接口的资源。这些接口定义了一个close()方法,用于释放资源。例如,文件流,网络连接,数据库连接等都是需要关闭的资源。

use函数的定义如下:

public inline fun <T : AutoCloseable?, R> T.use(block: (T) -> R): R

使用 use函数读取文件示例代码:

import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException

fun copyFile(source: File, target: File) {
    // 使用use函数自动关闭输入流和输出流
    FileInputStream(source).use { input ->
        FileOutputStream(target).use { output ->
            // 在use块中使用输入流和输出流
            val buffer = ByteArray(1024)
            var bytes = input.read(buffer)
            while (bytes >= 0) {
                output.write(buffer, 0, bytes)
                bytes = input.read(buffer)
            }
        }
    }
}

相关文章

  • Android性能优化---内存泄漏及解决

    Android内存泄漏专题分析 一、资源对象未关闭引起的内存泄漏 Android的资源对象在不再使用时,及时关闭对...

  • Android内存优化之内存泄漏

    内存泄漏 内存泄漏一般有以下几种情况:单例、静态变量、Handler、匿名内部类、资源使用未关闭 单例导致的内存泄...

  • Android 内存优化

    Android内存泄露容易导致内存溢出,又称为OOM。 内存泄漏怎么产生的 资源对象没关闭造成的内存泄漏 构造Ad...

  • 谈谈 LeakCanary 原理 --标准答案

    内存泄漏传统意义上的内存泄漏是至忘记手动释放内存,导致未释放的内存不可使用的现象。 jvm 的内存泄漏jvm的内存...

  • VideoView的内存泄漏问题

    解决内存泄漏之路 一、在XML文件直接用VideoView控件时,很容易造成内存泄漏,最开始出现的内存泄漏如下 谷...

  • 内存泄漏2021-04-08

    内存泄漏注意项 一.内存泄漏概念 1.什么是内存泄漏? 用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果...

  • 学习性能优化调试工具的使用——查找内存泄漏

    内存泄漏 原因:内存泄漏是由对象或者变量没有释放引起的,但实践证明并非所有的未释放的对象或变量都会导致内存泄漏,这...

  • 内存泄漏&内存溢出

    内存泄漏(memory leak) 申请了内存使用完毕后,并没有进行释放,这些未释放的内存称之为内存泄漏。 举个例...

  • android性能优化总结

    1,UI优化:这篇文章总结的不错 2,内存泄漏优化 常见的几种形式: 资源对象没关闭造成的内存泄漏: 资源对象没关...

  • Android性能优化之内存泄漏

    内存泄漏:内存单元使用完成后未释放,未回收。理解强弱引用和gc垃圾回收机制后,会更好的理解内存泄漏问题。 在目前的...

网友评论

      本文标题:内存泄漏之未关闭文件流

      本文链接:https://www.haomeiwen.com/subject/ksiaydtx.html