2016-06-22 4 views
-4

"ガベージコレクタ"からの干渉もなく、メモリ使用量を超えない安定したメモリが必要です。オブジェクトをエデンスペースJAVA8フォームをクリアするには?

package com.company; 

import org.apache.http.client.methods.CloseableHttpResponse; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.CloseableHttpClient; 
import org.apache.http.impl.client.HttpClientBuilder; 
import org.apache.http.util.EntityUtils; 
import java.net.URI; 

public class Main { 

    public static void main(String[] args) { 

     new GetThread().start(); 
    } 

    static class GetThread extends Thread { 

     private HttpGet httpGet = new HttpGet(); 
     private final CloseableHttpClient httpClient; 

     public GetThread() { 

      this.httpClient = HttpClientBuilder.create() 
        .build(); 

      try{ 
       httpGet.setURI(new URI("https://play.google.com/store/apps/details?id=com.whatsapp")); 
      } 
      catch (Exception e){ 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public void run() 
     { 
      StringBuilder body; 

      for (int i = 0; i < 50000; i++) 
      { 
       try{ 
        CloseableHttpResponse response = httpClient.execute(httpGet); 

        body = new StringBuilder(EntityUtils.toString(response.getEntity())); 

        EntityUtils.consume(response.getEntity()); 
        response.close(); 

        body.setLength(0); 

        response = null; 
        body = null; 
       } 
       catch (Exception e){ 
        e.printStackTrace(); 
       } 
      } 

     } 


    } 
} 

問題の線

本体= EntityUtils.toString(response.getEntity())。

このオブジェクトをnullとして設定しようとしましたが、まだEden空間に存在しています。

Yourkit graphs

Memory dump

オブジェクトがヌルであるが、「ガベージコレクタ」とメモリをきれいになるまで、それはまだメモリ内に存在します。

ありがとうございます!

+2

あなたがこれを行うべきではありません。 GCにその仕事をさせてください。私はそれに応じてGCを処理しているリアルタイムアプリケーションのJVMを探すことをお勧めします。 – duffymo

+0

オブジェクトをnullにすることはできません。変数には値 'null'を格納できます。ガベージコレクションのサイクルでヒープがクリアされます。なぜあなたは何か違うことを期待しているのですか? –

+0

[XY問題](http://xyproblem.info/)のような質問です。あなたは解決しようとしている実際のGCの問題について疑問を投げかけなければなりません。 – the8472

答えて

0

Edenからオブジェクトを削除することはできません.Genだけで行うことができます。 参照をnullに設定しても、オブジェクトが占める領域はクリアされません。

+0

だから、解決策はエデンスペースのサイズを制限することですか? – user3625158

+1

エデンスペースを制限する理由あなたは何をしようとしているのですか? gc-freeにしたい場合は非常に限られています。なぜここでそれをしたいですか?新しいオブジェクトを作成せず、作成したライブラリのいずれもそれらを作成しない場合は、gc-freeになります。 –

+0

GCが実行されているときは、毎回1〜3秒間プログラムがフリーズします。 オブジェクトからエデンスペースに生き続けるのを防ぐにはどうすればよいですか?ありがとうございます – user3625158

0

ガベージコレクションと増加(ヒープ)メモリ使用の両方を回避する唯一の方法は、ヒープに新しいオブジェクトを割り当てないことです。

メモリが割り当てられ、一定期間使用されて参照されなくなったJavaでは、ガベージコレクタはメモリを回復して再利用できるようにするメカニズムです。オブジェクトを作成して参照を停止すると、ガベージコレクタが実行されるまで、その部分を消費し続けます。

これは、Javaが動作するように設計されている方法です。

0

ソリューションは、再利用は、文字列を作成しないオブジェクト&に

package com.company; 

import org.apache.http.client.methods.CloseableHttpResponse; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.impl.client.CloseableHttpClient; 
import org.apache.http.impl.client.HttpClientBuilder; 
import org.apache.http.util.EntityUtils; 

import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.Reader; 
import java.net.URI; 

public class Main { 

    public static void main(String[] args) { 

     new GetThread().start(); 
    } 

    static class GetThread extends Thread { 

     private HttpGet httpGet = new HttpGet(); 

     private final CloseableHttpClient httpClient; 
     private CloseableHttpResponse response; 

     private StringBuilder content = new StringBuilder(); 
     private char[] buffer = new char[1024]; 


     public GetThread() { 

      this.httpClient = HttpClientBuilder.create() 
        .build(); 

      try{ 
       httpGet.setURI(new URI("https://play.google.com/store/apps/details?id=com.whatsapp")); 
      } 
      catch (Exception e){ 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public void run() 
     { 
      Reader in; 
      int rsz; 

      for (int i = 0; i < 50000; i++) 
      { 
       content.setLength(0); 

       try{ 
        response = httpClient.execute(httpGet); 

        InputStream is = response.getEntity().getContent(); 

        in = new InputStreamReader(is, "UTF-8"); 

        for (;;) 
        { 
         rsz = in.read(buffer, 0, buffer.length); 

         if (rsz < 0) 
          break; 

         content.append(buffer, 0, rsz); 
        } 

        in.close(); 

        EntityUtils.consume(response.getEntity()); 
        response.close(); 
       } 
       catch (Exception e){ 
        e.printStackTrace(); 
       } 
      } 
     } 

    } 
} 

このコードの最初のコードよりもはるかに優れ、プロファイリング結果 オブジェクトMmeory graphs

enter image description here

+0

これで、データの読み込みと削除が若干効率的になりましたが、データを使用していないため、操作全体が廃止されていることを考えると、それはまだ非常に非効率的です。おそらく、 'EntityUtils.consume(response。あなたが読んだデータを受け取っていないので、 'response = httpClient.execute(httpGet); EntityUtils.consume(response.getEntity())のほかにすべてがあります。 ; response.close(); 'を削除することができます。または、質問に投稿された元のコードに関して、問題のある行を削除したばかりです... – Holger

関連する問題