Memory leak - java heap space exception
---------------------------------------
Key: HTTPCLIENT-949
URL: https://issues.apache.org/jira/browse/HTTPCLIENT-949
Project: HttpComponents HttpClient
Issue Type: Bug
Components: HttpClient
Affects Versions: 4.0.1
Environment: Xp Sp3 on Intel Duo
Reporter: Andrea Braia
Priority: Critical
I use HttpComponents 4.0.1 and i have an application that has to do about 20
milions of requests, normal get and post request.
I suddenly engaged a memory leak problem... i found several post where many
users has the same problem, and they solve it in several ways... but no one
seem to be the right one.
The problem itself seems to be with Java Strings and the size of big String
handling.
For testing memory leak i used for retrive pages google.it, as you can see
below
*****************
//test class
public void test_HttpRequest(){
MyUtil.MyApp.AppHandler app_handler = new MyUtil.MyApp.AppHandler();
for(int i=0; i<10000; i++){
HttpGet httpget = new HttpGet("http://www.google.it/");
// HttpGet httpget = new HttpGet("http://www.comuni-italiani.it/");
httpget.setHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1;
en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0 (.NET CLR 3.5.30729)");
System.out.println("processing request num: "+(i+1));
new C_HttpRequestManager("google.it",
80,
httpget,
true,
5000,
false,//no proxy
null,
0,
app_handler).getResponse();
try {
System.out.println("waiting 2 s...");
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("requests completed, insert value...");
MyUtil.MyIO.Util.getLineFromStdInput();
}
*****************
now i show you the code about the http class request...
*****************
//C_HttpRequestManager
package MyIO;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpVersion;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.SingleClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.util.EntityUtils;
import BaseExcp.BaseExcp;
public class C_HttpRequestManager extends A_HttpRequestManager{
public final String class_name = "C_HttpRequestManager";
protected boolean keep_try;
protected int time_out;//ms, if zero use default
public C_HttpRequestManager(HttpParams _params, SchemeRegistry
_supportedSchemes, HttpHost _target_host, HttpRequestBase _request, boolean
_keep_try, int _time_out, MyUtil.MyApp.AppHandler _h_app){
this.params = _params;
this.supportedSchemes = _supportedSchemes;
this.target_host = _target_host;
this.request = _request;
this.keep_try = _keep_try;
this.time_out = _time_out;
if(time_out != 0){
this.params.setParameter(CoreConnectionPNames.SO_TIMEOUT ,
this.time_out);
}else{//use default timeout
this.params.setParameter(CoreConnectionPNames.SO_TIMEOUT , this.TIMEOUT);
}
this.app_handler = _h_app;
this.app_handler.addAppHandled(this);
}
public C_HttpRequestManager(String _target_host_name, int
_target_host_port, HttpRequestBase _request, boolean _keep_try, int
_time_out, boolean use_proxy, String proxy_host_name, int proxy_host_port,
MyUtil.MyApp.AppHandler _h_app){
this.params = new BasicHttpParams();
HttpProtocolParams.setVersion(this.params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(this.params, "UTF-8");
HttpProtocolParams.setUseExpectContinue(this.params, true);
this.supportedSchemes = new SchemeRegistry();
// Register the "http" and "https" protocol schemes, they are
// required by the default operator to look up socket factories.
this.supportedSchemes.register(new Scheme("http",
PlainSocketFactory.getSocketFactory(), 80));
this.supportedSchemes.register(new Scheme("https",
SSLSocketFactory.getSocketFactory(), 443));
this.target_host = new HttpHost(_target_host_name, _target_host_port);
this.request = _request;
this.keep_try = _keep_try;
this.time_out = _time_out;
if(time_out != 0){
this.params.setParameter(CoreConnectionPNames.SO_TIMEOUT ,
this.time_out);
}else{//use default timeout
this.params.setParameter(CoreConnectionPNames.SO_TIMEOUT , this.TIMEOUT);
}
//proxy config
if(use_proxy)
this.params.setParameter(ConnRoutePNames.DEFAULT_PROXY, new
HttpHost(proxy_host_name, proxy_host_port));
this.app_handler = _h_app;
this.app_handler.addAppHandled(this);
}
@Override
public void exitAppCarefully() {
if(ccm != null)
this.ccm.shutdown();
}
@Override
public C_HttpResponseStatusEntity getResponse() {
final String function_name = "getResponse";
final String function_name_formatted =
this.class_name+"."+function_name+": ";
C_HttpResponseStatusEntity response = null;
do{
ccm = new SingleClientConnManager(params, supportedSchemes);
httpclient = new DefaultHttpClient(ccm, params);
try {
h_response = httpclient.execute(target_host, request);
} catch (ClientProtocolException e) {
try {
if(this.app_handler.hasLog())
this.app_handler.log.writeErr(e.toString());
} catch (BaseExcp e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
this.h_status = e.toString();
this.h_entity = e.toString();
} catch (IOException e) {
response = this.pharse_IOException(e);
if(response.getStatus().equals(this.SocketTimeoutException)){
if(this.app_handler.hasLog()){
try {
this.app_handler.log.writeInfo(function_name_formatted+SocketTimeoutException);
} catch (BaseExcp e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
this.app_handler.exitAppCarefully();
}
}
continue;
}else{
return response;
}
}
this.h_status = h_response.getStatusLine().toString(); //Oleg is good to
use String? ...Should I?
//Oleg, here starts the
unsafe code, as learnd by posts found on internet... so below this commented
code starts the new code modified using StringBuffer and Streams....
//
// try {
// this.h_entity = EntityUtils.toString(this.h_response.getEntity());
//
// } catch (ParseException e) {
//
// try {
// if(this.app_handler.hasLog())
// this.app_handler.log.writeErr(e.toString());
// } catch (BaseExcp e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// }
//
// this.h_status = e.toString();
// this.h_entity = e.toString();
//
// } catch (IOException e) {
//
// response = this.pharse_IOException(e);
//
// if(response.getStatus().equals(this.SocketTimeoutException)){
// if(this.app_handler.hasLog()){
// try {
//this.app_handler.log.writeInfo(function_name_formatted+SocketTimeoutException);
// } catch (BaseExcp e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// this.app_handler.exitAppCarefully();
// }
// }
// continue;
// }else{
//
// return response;
// }
// }
// Get hold of the response entity
HttpEntity entity = this.h_response.getEntity();
// If the response does not enclose an entity, there is no need
// to bother about connection release
if (entity != null) {
InputStreamReader ir = null;
try {
ir = new InputStreamReader(entity.getContent());
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
char[] cbuf = new char[1024];
StringBuffer sbuf = new StringBuffer();
int len = 0;
int tot_len = 0;
try {
while((len = ir.read(cbuf)) > 0) {
sbuf.append(cbuf, 0, len);
tot_len = tot_len + len;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("tot_len: "+tot_len);
System.out.println("entity.getContentLength():
"+entity.getContentLength());
this.h_entity = sbuf.toString();
// Closing the input stream will trigger connection release
try {
ir.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.request.abort();
}
//System.out.println(this.h_status);
//System.out.println(this.h_entity);
this.keep_try = false;
}while(this.keep_try);
response = new C_HttpResponseStatusEntity(this.h_status, this.h_entity,
MyIO.C_HttpResponseStatusEntity.createHeaders(h_response.getAllHeaders()));
this.ccm.shutdown(); this.ccm = null;
return response;
}
}
*****************
well, i hope to hear from you soon...
Andrea
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]