記一次 JAVA 的內(nèi)存泄露分析

背景
jmap -histo:live `pid of java`
# 為了便于觀察,還是將輸出寫(xiě)入文件
jmap -histo:live `pid of java` > /tmp/jmap00
jmap -dump:format=b,file=heap.dump `pid of java離線分析




<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>4.1.3</version>
</dependency> public class HttpAsyncClient {
private CloseableHttpAsyncClient httpclient;
public HttpAsyncClient() {
httpclient = HttpAsyncClients.createDefault();
httpclient.start();
}
public void execute(HttpUriRequest request, FutureCallback<HttpResponse> callback){
httpclient.execute(request, callback);
}
public void close() throws IOException {
httpclient.close();
}
}
主要邏輯:
public class ReplayApplication {
public static void main(String[] args) throws InterruptedException {
//創(chuàng)建有內(nèi)存泄露的回放客戶端
ReplayWithProblem replay1 = new ReplayWithProblem();
//加載一萬(wàn)條請(qǐng)求數(shù)據(jù)放入緩存
List<HttpUriRequest> cache1 = replay1.loadMockRequest(10000);
//開(kāi)始循環(huán)回放
replay1.start(cache1);
}
}回放客戶端實(shí)現(xiàn)(內(nèi)存泄露):
public class ReplayWithProblem {
public List<HttpUriRequest> loadMockRequest(int n){
List<HttpUriRequest> cache = new ArrayList<HttpUriRequest>(n);
for (int i = 0; i < n; i++) {
HttpGet request = new HttpGet("http://www.baidu.com?a="+i);
cache.add(request);
}
return cache;
}
public void start(List<HttpUriRequest> cache) throws InterruptedException {
HttpAsyncClient httpClient = new HttpAsyncClient();
int i = 0;
while (true){
final HttpUriRequest request = cache.get(i%cache.size());
httpClient.execute(request, new FutureCallback<HttpResponse>() {
public void completed(final HttpResponse response) {
System.out.println(request.getRequestLine() + "->" + response.getStatusLine());
}
public void failed(final Exception ex) {
System.out.println(request.getRequestLine() + "->" + ex);
}
public void cancelled() {
System.out.println(request.getRequestLine() + " cancelled");
}
});
i++;
Thread.sleep(100);
}
}
}內(nèi)存分析:
1.啟動(dòng)情況:








代碼優(yōu)化
public class ReplayApplication {
public static void main(String[] args) throws InterruptedException {
ReplayWithoutProblem replay2 = new ReplayWithoutProblem();
List<String> cache2 = replay2.loadMockRequest(10000);
replay2.start(cache2);
}
}
public class ReplayWithoutProblem {
public List<String> loadMockRequest(int n){
List<String> cache = new ArrayList<String>(n);
for (int i = 0; i < n; i++) {
cache.add("http://www.baidu.com?a="+i);
}
return cache;
}
public void start(List<String> cache) throws InterruptedException {
HttpAsyncClient httpClient = new HttpAsyncClient();
int i = 0;
while (true){
String url = cache.get(i%cache.size());
final HttpGet request = new HttpGet(url);
httpClient.execute(request, new FutureCallback<HttpResponse>() {
public void completed(final HttpResponse response) {
System.out.println(request.getRequestLine() + "->" + response.getStatusLine());
}
public void failed(final Exception ex) {
System.out.println(request.getRequestLine() + "->" + ex);
}
public void cancelled() {
System.out.println(request.getRequestLine() + " cancelled");
}
});
i++;
Thread.sleep(100);
}
}
}
結(jié)果驗(yàn)證





總結(jié)
- END - 最近熱文
? 新來(lái)的妹紙rm -rf把公司整個(gè)數(shù)據(jù)庫(kù)刪沒(méi)了,整個(gè)項(xiàng)目組慌了~ ? 2021年7月程序員工資統(tǒng)計(jì),平均15302元 ? 那些學(xué)計(jì)算機(jī)的女生后來(lái)都怎么樣了? ? 字節(jié)跳動(dòng)取消大小周,員工卻高興不起來(lái)!內(nèi)網(wǎng)哀嚎:變相降薪20%,少賺一萬(wàn)!
評(píng)論
圖片
表情
