2010-07-14 29 views
0

我刚开始写一个简单的网络爬虫来获取我们进入系统的链接信息。我使用httpclient 4.x.我有大约100个线程运行获取链接并对它们进行头部请求,它在最初的几个小时内运行很好,然后减慢到尖锐的抓取。我不确定是否正确设置了连接管理器。关于httpclient性能的困惑

这里是我必须创建一个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); 

     } 
    }; 

更新: 我跑的视觉VM了一个小时左右,这里的记忆在远程进程曲线图中,存储器是现在使用最多

http://img64.imageshack.us/f/screenshot20100714at204.png/

+0

我知道你说内存看起来很稳定,但是你启用了GC日志记录吗?你在GC上花费了多少时间? – bwawok 2010-07-14 16:05:43

+0

我其实并不是很新,对于java来说很新,所以不知道我可能会在哪里设置 – James 2010-07-14 16:08:13

+0

你是网络I/O绑定的,100个线程可能使你的网络连接饱和。然后你就是磁盘I/O绑定。 – 2010-07-14 16:40:50

回答

1

使用VisualVM(它还带有JD K)并使用JMX监视您的应用程序一段时间。同时安装Visual GC插件,它提供了GC的内部情况(如果没有足够的内存,这可能会使应用程序变慢)。

当速度变慢时,请查看线程标签以查看锁定时的外观。锁定或没有足够的内存(内存泄漏)应该是你的情况的问题。

如果您想深入了解,我会向您推荐YourKit Java Profiler。

0

我也会尝试调整线程数,看看是否有任何区别。