缓冲读取器和网站的高内存使用率

时间:2013-11-02 16:26:19

标签: java multithreading url memory bufferedreader

我写了一个程序,它连接到网站并获取网页的标题。我从一个可以插入程序中的文本中获取URL,然后所有URL都在列表中。为了加快速度,我使用了多个线程。如果我有例如10个线程和10个URL,我的程序使用大约100 MB的内存。但是如果我有5个线程和10个URL,那么每个线程必须连接到两个网站,我的内存使用量大约为1.3 GB。我发现它是代码中的一行,它使我的程序使用了如此多的内存:

in = new BufferedReader(new InputStreamReader(spoof.getInputStream()));

在这种方法中:

private BufferedReader in;
private URL url;
private URLConnection spoof;

private void openConnection() {

    try {
        url = new URL(tag.url);
        spoof = url.openConnection();
        spoof.setRequestProperty("User-Agent", userAgent);

        in = new BufferedReader(new InputStreamReader(spoof.getInputStream()));

    } catch (IOException ex) {
        tag.ableToConnect = false;
    }
}

我尝试关闭BufferedReader并运行手册System.gc()。两者都对内存使用没有影响。

如果你能帮助我,我会很高兴的。谢谢!

3 个答案:

答案 0 :(得分:2)

  

如果我有10个线程和10个URL,我的程序使用大约100 MB的内存。

一般性评论。

  1. 在任何时间点存在10个(或100个)BufferedReader个对象当然没有问题。默认缓冲区大小为8k字符或16k字节。其中100个将是几个megs。每个帖子应该一次从一个BufferedReader读取,您应该close()并设置为null(见下文)in块中的try {} finally {}确保正确释放内存,即使是IOException

  2. 如果内存泄漏确实在BufferedReader,那么你显然是以某种方式保留对它们的引用。在它上面调用close()是不够的,因为它不会释放底层缓冲区。您应该将in字段和引用它们的其他位置设置为null,以确保GC可以获得它。也许持有BufferedReader的班级会被收藏在一个集合中?

  3. 要考虑的一件事是限制队列中未完成的URL数量。了解URL队列的大小可能会告诉您队列中保留的内存量。您可能会考虑使用String而不是URL或更重的队列。限制队列的大小将无法正常工作,因为它会阻止您的线程处理页面,甚至可能导致死锁。

答案 1 :(得分:0)

1)尝试使用inputstreamreader 2)不要尝试读取按行读取的所有块

public class BufferedReaderExample {   

    public static void main(String args[]) {

        //reading file line by line in Java using BufferedReader       
        FileInputStream fis = null;
        BufferedReader reader = null;

        try {
            fis = new FileInputStream("C:/sample.txt");
            reader = new BufferedReader(new InputStreamReader(fis));

            System.out.println("Reading File line by line using BufferedReader");

            String line = reader.readLine();
            while(line != null){
                System.out.println(line);
                line = reader.readLine();
            }           

        } catch (FileNotFoundException ex) {
            Logger.getLogger(BufferedReaderExample.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(BufferedReaderExample.class.getName()).log(Level.SEVERE, null, ex);

        } finally {
            try {
                reader.close();
                fis.close();
            } catch (IOException ex) {
                Logger.getLogger(BufferedReaderExample.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
  } 

了解详情:http://javarevisited.blogspot.com/2012/07/read-file-line-by-line-java-example-scanner.html#ixzz2jVVs2RMN 如果速度证明是一个问题,你可以看一下[java.nio] [1]包 - 那些应该比java.io快,

答案 2 :(得分:-1)

我不确定它会有所帮助,但你也应该关闭InputStreamReader。