关于httpclient性能的困惑

时间:2010-07-14 16:01:59

标签: java httpclient

我刚开始编写一个简单的网络抓取工具,以获取我们进入系统的链接信息。我正在使用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一个小时左右,这是远程进程的内存图,内存现用完了

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

2 个答案:

答案 0 :(得分:1)

使用VisualVM(它还附带JDK)并使用JMX监视您的应用程序一段时间。还安装了Visual GC插件,它提供了GC的内部结构(如果没有足够的内存,可能会大大减慢应用程序的负担)。

当它变慢时,请查看“线程”选项卡以查看锁定时的外观。在你的情况下,锁定或没有足够的内存(内存泄漏)应该是问题。

如果你想更深入,我建议你使用YourKit Java Profiler。

答案 1 :(得分:0)

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