2016-06-22 11 views
-4

Ich möchte, dass der Speicher stabil ist, ohne Störungen durch den "Garbage Collector" und auch die Speichernutzung wird nicht überschritten.Wie lösche ich Objekte von eden space 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(); 
       } 
      } 

     } 


    } 
} 

Problematische Linie

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

Ich habe versucht, dieses Objekt als null zu setzen, aber es existiert immer noch im Eden-Raum.

Yourkit graphs

Memory dump

obwohl das Objekt null ist, ist es in dem Speicher noch existiert, bis der „Garbage Collector“, um den Speicher reinigt.

Danke!

+2

Sie sollten nicht tun . Lass den GC seine Arbeit machen. Ich würde empfehlen, nach einer JVM für Echtzeit-Apps zu suchen, die sich entsprechend mit GC befasst haben. – duffymo

+0

Objekte können nicht null sein. Variablen können den Wert "null" speichern. Der Heap wird bei Speicherbereinigungszyklen gelöscht. Warum erwartest oder willst du etwas anderes? –

+0

Klingt wie eine [XY-Problem] (http://xyproduct.info/) Frage. Sie sollten eine Frage (infundiert mit umsetzbaren Daten!) Über das eigentliche GC-Problem stellen, das Sie lösen möchten. – the8472

Antwort

0

Sie können kein Objekt aus Eden entfernen, nur GC kann es tun. Durch Setzen der Referenz auf null wird der vom Objekt belegte Speicherplatz nicht gelöscht.

+0

Also, die Lösung ist, die eden Raumgröße zu begrenzen? – user3625158

+1

Warum begrenzen eden space? Was versuchst du zu machen? Es gibt nur sehr wenige Fälle, in denen Sie gc-frei sein möchten. Warum willst du es hier? Sie werden gc-frei sein, wenn Sie keine neuen Objekte erstellen und keine der von Ihnen erstellten Bibliotheken sie erstellen. –

+0

Wenn GC läuft, friert das Programm jedes Mal für 1-3 Sekunden ein. Was kann ich tun, um zu verhindern, dass Objekte im Eden-Raum lebendig bleiben? Vielen Dank – user3625158

0

Die einzige Möglichkeit, sowohl die Speicherbereinigung als auch die (Heap-) Speicherbelegung zu vermeiden, besteht darin, keine neuen Objekte auf dem Heap zuzuweisen.

In Java, wenn Speicher zugeordnet ist, für einen bestimmten Zeitraum verwendet und dann nicht mehr referenziert wird, ist der Garbage Collector der Mechanismus, der den Speicher wiederherstellt und für die Wiederverwendung verfügbar macht. Wenn Sie Objekte erstellen und dann nicht mehr auf sie verweisen, verbrauchen sie weiterhin diesen Teil des Heapspeichers, bis der Garbage Collector ausgeführt wird.

Es ist nur die Art, wie Java entwickelt wurde.

0

Lösung, Reuse in Objekte & nicht Zeichenfolge erstellen Objekte

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(); 
       } 
      } 
     } 

    } 
} 

Dieser Code viel besser als der erste Code, Profilieren Ergebnisse Mmeory graphs

enter image description here

+0

Sie lesen und löschen die Daten jetzt etwas effizienter, aber wenn Sie bedenken, dass die gesamte Operation obsolet ist, weil Sie die Daten nicht verwenden, ist sie immer noch unglaublich ineffizient. Vielleicht, die Zeile 'EntityUtils.consume (Antwort.getEntity()); 'tut etwas, aber das ist das einzige (und es empfängt nicht die Daten, die Sie gelesen haben. Also alles außer' response = httpClient.execute (httpGet); EntityUtils.consume (response.getEntity()) ; response.close(); 'kann entfernt werden. Oder in Bezug auf Ihren ursprünglichen Code, der in der Frage gepostet wurde, hätten Sie einfach die problematische Zeile entfernen können ... – Holger