httpclients 4.5.4를 사용하는 동안 문제가 발생했습니다. 연결과 관련된 모든 것을 닫으면 Java GC에서 PoolingHttpClientConnectionManager 개체를 수집 할 수 없습니다. 약 1 개월 동안 응용 프로그램이 실행되므로 OOM 예외가 발생합니다. 내 코드는 https://hc.apache.org/httpcomponents-client-4.5.x/httpclient/examples/org/apache/http/examples/client/ClientConnectionRelease.java의 예와 같습니다. InternalHttpClient 객체는 Java GC로도 수집 할 수 없습니다. 아래 코드에는 두 클래스에 대한 참조가 들어있는 객체가 있습니까?httpclient4.5.4에서 PoolingHttpClientConnectionManager를 해제하는 방법
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HttpUtil {
private static Logger logger = LoggerFactory.getLogger(HttpUtil.class);
/**
* Http post请求
*/
public static String doHttpPost(String postUrl, Map<String, String> headers,
Map<String,String> params,String filePath) {
try {
CloseableHttpClient httpClient = HttpClients.createDefault();
try {
HttpPost post = getHttpPost(postUrl, headers, params, filePath);
CloseableHttpResponse response = httpClient.execute(post);
try {
InputStream inputStream = null;
InputStreamReader inputStreamReader = null;
BufferedReader bufferedReader = null;
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
try {
inputStream = response.getEntity().getContent();
inputStreamReader = new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(inputStreamReader);
return bufferedReader.readLine();
}catch (Exception e) {
logger.warn("do http post fail : ", e);
}finally {
if (bufferedReader != null) {
logger.info("release bufferedReader: " + filePath);
bufferedReader.close();
}
if (inputStreamReader != null) {
logger.info("release inputStreamReader: " +filePath);
inputStreamReader.close();
}
if (inputStream != null) {
logger.info("release inputStream: " +filePath);
inputStream.close();
}
}
}
} catch (Exception e) {
logger.warn("do http post fail: ", e);
} finally {
if (response != null) {
logger.info("release response: " + filePath);
response.close();
}
if (post != null) {
logger.info("release HttpPost: " + filePath);
post.releaseConnection();
}
}
} catch (Exception e) {
logger.warn("do http post fail: ", e);
} finally {
if (httpClient != null) {
logger.info("release httpClient: " + filePath);
httpClient.close();
logger.info("release connectionManager: " + filePath);
httpClient.getConnectionManager().shutdown();
}
}
} catch (Exception e) {
logger.warn("do http post fail: ", e);
}
return "";
}
private static HttpPost getHttpPost(String postUrl, Map<String, String> headers,
Map<String, String> params, String filePath) {
HttpPost post = new HttpPost(postUrl);
String[] headerKeys = headers.keySet().toArray(new String[headers.keySet().size()]);
for (String key : headerKeys) {
post.setHeader(key, headers.get(key));
}
FileBody fileBody = new FileBody(new File(filePath));
MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
multipartEntityBuilder.addPart("express_image", fileBody);
String[] paramKeys = params.keySet().toArray(new String[params.keySet().size()]);
for (String key : paramKeys) {
StringBody valueBody = new StringBody(params.get(key), ContentType.TEXT_PLAIN);
multipartEntityBuilder.addPart(key, valueBody);
}
post.setEntity(multipartEntityBuilder.build());
return post;
}
}
답변을 얻었습니다. 또 다른 클래스는 PoolingHttpClientConnectionManager를 사용하고 풀어주지 않았습니다. 나는 매트 메모리 맵 분석에서 그들을 발견했다. 모두 감사합니다. –