Java字符串内存泄漏II

问题描述

| 我之前也曾问过类似的问题:Java字符串内存泄漏 但是我不确定要问什么: 这是我编写的另一段代码
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;


public class TestString {
    public static int  readLineXX(BufferedReader br) throws Exception {
            String s = br.readLine();
            if ( s == null ) return 0;
            return 1;
    }
    public static void main(String args[]) {
        while (true) {
        try {
            FileInputStream fstream = new FileInputStream(\"bigfile.txt\");
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader  br = new BufferedReader(new InputStreamReader(in));
            while ( readLineXX (br)!= 0) {
                //System.out.print(\".\");
            }
            br.close();
            in.close();
            fstream.close();
        } catch (Exception e) {
        }       
    }
    }
}
由于Java中的String是不可变的,因此将“ 1”作为垃圾回收。 我使用
-verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails
选项长时间运行了此代码,它运行良好。 这是我的主应用程序的小片段代码,我认为这是泄漏并导致
OOM
bigfile.txt
1GB
附近。     

解决方法

是的,
s
将被垃圾收集。保持不可变不会阻止其被垃圾回收,而只是防止对其进行修改。 请注意,如果该行很大,则“ 7”可能会占用大量内存。例如,如果您的文本文件是1gb,没有任何换行符,那么
br.readLine()
很有可能会消耗2gb,1gb用于读取的数据,然后1gb用于创建的字符串。     ,代码中的ѭ9不会导致内存泄漏,因为从ѭ10返回后,它们在任何地方都没有被引用,因此所有垃圾都会被回收。我的怀疑对象是您正在使用的流。我完全可以想象,对于1GB的输入文件,输入流会变得非常大。 一种测试方法是将输入文件切成两部分或更多部分,然后依次读取它们中的每一个。如果罪魁祸首是流,则一个接一个地读取几个较小的输入文件不应导致内存泄漏。     ,代替
        FileInputStream fstream = new FileInputStream(\"bigfile.txt\");
        DataInputStream in = new DataInputStream(fstream);
        BufferedReader  br = new BufferedReader(new InputStreamReader(in));
你可以用
        BufferedReader  br = new BufferedReader(new FileReader(\"bigfile.txt\"));
导致OOME的唯一方法是行数非常长且内存有限。您是否正在使用-Xmx选项?为什么使用DataInputStream-是二进制数据还是文本数据?     ,代码中没有明显的内存泄漏。 使用
-XX:+HeapDumpOnOutOfMemoryError
JVM参数转储堆并分析结果。 (我假设使用Java 6 Hotspot JVM;如果使用的是其他Java JVM,则可能会有类似的选择。) ѭ14是多余的;流应该在finally块中关闭;但我看不到这种情况如何影响您报告的错误。