Java字符串内存泄漏二

发布于 2024-11-08 14:24:22 字数 1322 浏览 0 评论 0原文

我之前问过类似的问题: Java String Memory Leak

但我不确定问什么:

这是我写的另一段代码:

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是不可变的,String会被垃圾收集吗? 我使用 -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails 选项运行此代码很长时间,运行良好。

这是我的主应用程序的小片段代码,我认为其中存在泄漏并导致OOMbigfile.txt 大约为 1GB

I have ask similar question before : Java String Memory Leak

But I was not sure what to ask:

Here is another piece of code I wrote:

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) {
        }       
    }
    }
}

Since the String in Java are Immutable, will the String s be garbage collected.
I ran this code for long time using -verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails options, It is running fine.

This is small snippet code of my main application where I think is leak and causing OOM.
bigfile.txt is around 1GB.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

笑看君怀她人 2024-11-15 14:24:22

是的,s 将被垃圾收集。不可变并不能阻止它被垃圾收集,它只是阻止它被修改。

请注意,如果行非常大,br.readlLine() 可能会使用大量内存。例如,如果您的文本文件大小为 1gb,没有任何换行符,则 br.readLine() 很可能会消耗 2gb,其中 1gb 用于读入的数据,然后 1gb 用于读取数据。创建的字符串。

Yes, s will be garbage collected. Being immutable does not prevent it from being garbage collected, it just prevents it from being modified.

Note that br.readlLine() will potentially use a large amount of memory if the line is very large. For example, if your text file is 1gb without any line breaks, then it is quite possible for br.readLine() to consume 2gb, 1gb for the data that is read in, and then 1gb for the created string.

筑梦 2024-11-15 14:24:22

代码中的 String 不会导致内存泄漏,因为从 readLineXX 返回后,它们不会在任何地方被引用,因此所有内容都会被垃圾收集。我的怀疑是你正在使用的流。我可以想象,对于 1GB 的输入文件,输入流可能会变得相当大。

测试这一点的一种方法是将输入文件切成两个或更多部分,然后依次读取每个部分。如果罪魁祸首是流,那么逐个读取几个较小的输入文件应该不会导致内存泄漏。

The Strings in your code can't cause memory leak, as they aren't referenced anywhere after returning from readLineXX, so all will get garbage collected. My suspects are rather the streams you are using. I can well imagine that for a 1GB input file the input streams can get pretty big.

One way to test this would be to cut your input file into 2 or more parts, and read each of them in turn. If the culprits are the streams, reading several smaller input files one by one should not cause a memory leak.

谜泪 2024-11-15 14:24:22

而不是

        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 - 这是二进制数据还是文本数据?

instead of

        FileInputStream fstream = new FileInputStream("bigfile.txt");
        DataInputStream in = new DataInputStream(fstream);
        BufferedReader  br = new BufferedReader(new InputStreamReader(in));

you could use

        BufferedReader  br = new BufferedReader(new FileReader("bigfile.txt"));

The only way to cause an OOME is having very long lines and limited memory. Are you using -Xmx options? Why are you using DataInputStream - is this binary or text data?

樱花坊 2024-11-15 14:24:22

代码中没有明显的内存泄漏。

使用 -XX 转储堆: +HeapDumpOnOutOfMemoryError JVM 参数并分析结果。 (我假设 Java 6 Hotspot JVM;如果您使用另一个,可能会有类似的选项。)

DataInputStream 是多余的;流应该在finally块中关闭;但我不明白这些事情会如何影响您报告的错误。

There are no obvious memory leaks in the code.

Dump the heap with the -XX:+HeapDumpOnOutOfMemoryError JVM argument and analyse the results. (I'm assuming a Java 6 Hotspot JVM; if you're using another, there will likely be similar options.)

The DataInputStream is redundant; streams should be closed in finally blocks; but I don't see how such things could influence the errors you are reporting.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文