我刚开始编写一个简单的网络抓取工具,以获取我们进入系统的链接信息。我正在使用httpclient 4.x.我有大约100个线程正在运行获取链接并对它们执行头部请求,它在前几个小时运行良好,然后它减慢到尖锐的爬行。我不确定我是否正确设置了连接管理器。
这是我必须创建一个httpclient对象的代码。任何人都会看到任何会引发此代码块警报的内容?当我停止服务器并重新启动它时,一切都和新的一样好。在运行缓慢的阶段,内存在每个进程稳定的500K时仍然看起来不错,所以它看起来不像是在泄漏内存。
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
HttpConnectionParams.setSoTimeout(httpParams, 5000);
ConnManagerParams.setMaxTotalConnections(httpParams, 200);
HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);
// set request params
httpParams.setParameter("http.protocol.cookie-policy", CookiePolicy.BROWSER_COMPATIBILITY);
httpParams.setParameter("http.useragent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", PlainSocketFactory.getSocketFactory(), 443));
final ClientConnectionManager cm = new ThreadSafeClientConnManager(httpParams,schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(cm, httpParams);
httpClient.getParams().setParameter("http.conn-manager.timeout", 10000L);
httpClient.getParams().setParameter("http.protocol.wait-for-continue", 10000L);
我也在线程中使用此代码来清理文档中提到的过期连接
final Runnable cleanUp = new Runnable() {
public void run() {
cm.closeExpiredConnections();
// Optionally, close connections
// that have been idle longer than 30 sec
cm.closeIdleConnections(30, TimeUnit.SECONDS);
}
};
更新: 我运行了Visual VM一个小时左右,这是远程进程的内存图,内存现用完了
答案 0 :(得分:1)
使用VisualVM(它还附带JDK)并使用JMX监视您的应用程序一段时间。还安装了Visual GC插件,它提供了GC的内部结构(如果没有足够的内存,可能会大大减慢应用程序的负担)。
当它变慢时,请查看“线程”选项卡以查看锁定时的外观。在你的情况下,锁定或没有足够的内存(内存泄漏)应该是问题。
如果你想更深入,我建议你使用YourKit Java Profiler。
答案 1 :(得分:0)
我也会尝试调整线程数,看看是否有任何不同。