首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >缓存器和网站的高内存使用率

缓存器和网站的高内存使用率
EN

Stack Overflow用户
提问于 2013-11-02 16:26:18
回答 3查看 4.6K关注 0票数 1

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

代码语言:javascript
复制
in = new BufferedReader(new InputStreamReader(spoof.getInputStream()));

在这种方法中:

代码语言:javascript
复制
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()。两者都对内存使用没有影响。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-11-03 15:39:57

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

几点一般性意见。

  1. 当然,在任何时候都有10个(或100个) BufferedReader对象是没有问题的。默认缓冲区大小为8k字符或16k字节。他们中的100人将是一对巨怪。每个线程应该一次从一个BufferedReader读取,并且您应该将close()设置为try {} finally {}块中的in (参见下面),以确保正确释放内存,即使在IOException的情况下也是如此。
  2. 如果内存泄漏确实与BufferedReader有关,那么显然是在以某种方式保留对它们的引用。只在上面调用close()是不够的,因为它不会释放底层缓冲区。您应该将in字段和引用它们的其他地方设置为null,以确保GC能够获得它。也许持有BufferedReader的类被保存在一个集合或其他什么地方?
  3. 需要考虑的一件事是限制队列中未完成的URL的数量。知道URL队列的大小可能会告诉您队列本身保存的内存量。您可能会考虑只使用一个String队列,而不是URL或其他更重的队列。限制队列的大小不能完美地工作,因为它会阻止线程处理页面,甚至可能导致死锁。
票数 2
EN

Stack Overflow用户

发布于 2013-11-02 16:42:55

2)不要尝试逐行读取所有块

代码语言:javascript
复制
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包--这些包应该比java.io更快,

票数 0
EN

Stack Overflow用户

发布于 2013-11-02 16:42:15

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

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19744086

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档