cot*_*aws 14 java android memory-leaks httpclient threadpool
我有一个应用程序,它有一个线程池(ThreadPoolExecutor),它是每个执行HttpGet操作的传递任务,并将InputStream读入byte []以执行某些操作.
在阅读了HttpClient文档后,我得出的结论是,跨多个线程管理HttpClient连接的最佳方法是创建一个ThreadSafeClientConnManager并在整个应用程序中共享它.
实现这一点之后,我注意到即使在完成所有任务之后,仍然有大量内存仍由ThreadSafeClientConnManager使用.
查看堆转储,此内存采用byte []数组的形式.这些不是我创建的任何引用.它们由ThreadSafeClientConnManager及其池的各个部分保存.我不确定它们是否与InputStream相关或者它们是否是其他内容.
所有任务本身及其变量都被成功地垃圾收集.
如果我在ThreadSafeClientConnManager上调用getConnectionManager().shutdown(),则释放所有内存就好了.但是,我不想关闭连接,因为这些HttpGet任务可能随时发生.我希望在应用程序生命期间保持打开状态.
随着HttpGet任务的运行,持有的内存越来越多,最终可能导致内存不足错误.任务完成后,内存不会被释放.
在完成使用它的任务后,如何确保释放内存?
这是我正在使用的代码.它与HttpClient文档中的代码拼凑在一起,其他问题在SO和在线上.
HttpClient的创建:
// Create and initialize HTTP parameters
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 40 * 1000);
HttpConnectionParams.setSoTimeout(params, 40 * 1000);
ConnManagerParams.setMaxTotalConnections(params, 100);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
// Create and initialize scheme registry
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register( new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
// Create an HttpClient with the ThreadSafeClientConnManager.
// This connection manager must be used if more than one thread will
// be using the HttpClient.
ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
mHttpClient = new DefaultHttpClient(cm, params);
Run Code Online (Sandbox Code Playgroud)
然后,执行HTTPGET了Runnable是非常准确地从该例如基于HttpClient的实例为手动连接释放.以下是它的外观示例:
HttpClient httpclient = getTheSharedThreadSafeClientConnManager(); // Would return the mHttpClient from above
try {
HttpGet httpget = new HttpGet("http://www.apache.org/");
// Execute HTTP request
System.out.println("executing request " + httpget.getURI());
HttpResponse response = httpclient.execute(httpget);
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
System.out.println("----------------------------------------");
// Get hold of the response entity
HttpEntity entity = response.getEntity();
// If the response does not enclose an entity, there is no need
// to bother about connection release
if (entity != null) {
InputStream instream = entity.getContent();
try {
instream.read();
// do something useful with the response
} catch (IOException ex) {
// In case of an IOException the connection will be released
// back to the connection manager automatically
throw ex;
} catch (RuntimeException ex) {
// In case of an unexpected exception you may want to abort
// the HTTP request in order to shut down the underlying
// connection immediately.
httpget.abort();
throw ex;
} finally {
// Closing the input stream will trigger connection release
try { instream.close(); } catch (Exception ignore) {}
}
}
}
Run Code Online (Sandbox Code Playgroud)
是否需要做更多的事情来释放每项任务的资源?我在他们的ThreadSafeClientConnManager示例中看到他们使用了HttpContext,但我找不到任何关于如何使用它的文档.这需要吗?如果是这样,你如何使用ThreadPoolExecutor?
非常感谢.
| 归档时间: |
|
| 查看次数: |
7416 次 |
| 最近记录: |