我刚刚开始编写一个简单的Web搜寻器,以获取有关我们进入系统的链接的信息。我正在使用httpclient4.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);
}
};
更新:
我运行了视觉虚拟机一个小时左右,这是远程进程上的内存图,现在内存已用完
http://img64.imageshack.us/f/screenshot20100714at204.png/
最佳答案
使用VisualVM(JDK附带),并使用JMX监视您的应用程序一段时间。还要安装Visual GC插件,它提供了有关GC的内部信息(如果没有足够的内存,这可能会使应用程序减慢很多速度)。
当速度变慢时,请查看“线程”选项卡以查看锁定时的外观。锁定或内存不足(内存泄漏)可能是您遇到的问题。
如果您想更深入一点,我建议您使用YourKit Java Profiler。