多线程使用中的变量声明,Java [内存泄漏问题]

时间:2014-05-08 19:14:47

标签: java multithreading memory-leaks

我正在使用Java中的Jsoup库构建一个爬虫程序。

代码结构如下:

public static BoneCP connectionPool = null;
public static Document doc = null;
public static Elements questions = null;
static
{

        // Connection Pool Created here
}

在MAIN方法中,我从 10个不同的主题中调用了 getSeed()方法。

getSeed()方法从数据库中选择1个随机网址,然后将其转发给 processPage()方法。

processPage()方法使用jSoup库连接到从 getSeed()方法传递的URL,并从中提取所有URL,并进一步将它们全部添加到数据库中。

此过程持续24x7。

问题是: 在processPage()方法中,它首先使用:

连接到getSeed()方法发送的URL
doc = Jsoup.connect(URL)

然后,对于通过访问该特定URL找到的每个URL,jSoup将再次建立新连接。

questions = doc.select("a[href]");
for(Element link: questions)
{
doc_child = Jsoup.connect(link.attr("abs:href"))
}

现在,如果我将doc和questions变量声明为全局变量并在processPage()方法中进行整个处理后将它们归零,则会解决内存泄漏问题,但其他线程会停止,因为doc和问题会在两者之间变为空白。接下来我该怎么办?

1 个答案:

答案 0 :(得分:2)

如果你使用的是静态字段,特别是对于那种状态,那就是“错误的设计”,并且基于你的描述,它似乎表现得非常不安全。我不知道为什么你认为手头有内存泄漏,但不管它是什么,如果东西是有序的,它更容易诊断。

我要说的是,尝试根据以下内容进行工作:

class YieldLinks implements Callable<Set<URI>>{
    final URI seed;
    YieldLinks(URI seed){
        this.seed = seed;
    }
}


public static void main(String[] args){
    Set<URI> links = new HashSet<>();
    for(URI uri : seeds){
        YieldLinks yieldLinks = new YieldLinks(uri);
        links.addAll(yieldLinks.call());
    }
}

一旦这个单线程的东西工作正常,你可以看看添加线程。