Mögliches heap space lokalisieren

Nisbo

Bekanntes Mitglied
Servus,

ich weiß der Text ist länger und so etwas wird gerne mal nich tgelesen aber evtl findet sich ja doch der eine oder andere :)

ich habe ein Programm (Private für den Amaterufunkbereich, also absolut kostenlos) welches sich zu einen MQTT Server verbindet (QOS 0 und 2 je nach Topic) dann die Daten auswertet und ausgewählte bzw aufbereitete Daten an einen anderen MQTT Broker weiter leitet. (QOS 2)

Auf den Broker wo die Daten her kommen habe ich keinen Zugriff, auf den Broker wo die Daten hin gehen habe ich Zugriff.

Das Programm läuft jetzt 48 Stunden und
- hat 56 Millionen Nachrichten empfangen und verarbeitet (10,4 GB)
- 702.000 Nachrichten weitergeleitet

Das Programm startet mit etwa 50 MB im RAM und hatte jetzt 680 MB im RAM (läuft auf einem 2010er Windows vServer mit nur 2 GB RAM und 2 Kernen) und nähert sich extrem der 100% RAM Auslastung des vServers.

Vor 2 Tagen hatte ich den Error bekommen und das Programm ist ausgestiegen
Code:
Exception in thread "Timer-0" java.lang.OutOfMemoryError: Java heap space

Das Programm läuft noch in Eclipse so das ich Fehler besser auswerten kann.

Der Timer ist von meinem "WatchDog" welcher alle 15 Sekunden guckt ob noch Messages empfangen worden sind bzw weitergeleitet worden sind. Wenn nicht wird der jeweilige MQTT Client beendet und neu gestartet. Hierbei schicke ich mir auch eine Nachricht per Telegram.

Das nur als Info was der Timer macht, der Timer wird nach Programmstart automatisch gestartet aber den Timer selbst mache ich dafür jetzt nicht wirklich verantwortlich.

So schaut der Timer aus:
Java:
    private void startTimerTask(){
        this.timerTask = new TimerTask() {
            public void run() {
                watchDogSeconds--;
                labelWatchDogTimer.setText(String.valueOf(watchDogSeconds));
               
                if(watchDogSeconds == 0) {
                    watchDogSeconds = 15;
                    labelWatchDogTimer.setText(String.valueOf(watchDogSeconds));
                   
                    if(watchDogCounterLH == messagesSendLastHeard) {
                        System.out.println("LH Server - Restart needed");
                       
                        // Restart RR Server
                        try {
                            System.out.println("WatchDog - Try to Restart LH Server - Before Telegram Message");
                            sendTelegramMessage("WatchDog - Try to Restart LH Server");
                            System.out.println("WatchDog - Try to Restart LH Server - After Telegram Message");
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                       
                        watchDogDontSendTelegram = true;
                        System.out.println("WatchDog - Try to Restart LH Server - Before startWebSocketServer");
                        startRRmqttBroker();
                        System.out.println("WatchDog - Try to Restart LH Server - Before startWebSocketServer");
                        watchDogDontSendTelegram = false;
                    }
                   
                    if(watchDogCounterMQTT == messagesReceived) {
                        System.out.println("MQTT Client - Restart needed");
                       
                        // Restart MQTT
                        try {
                            System.out.println("WatchDog - Try to Restart MQTT Client - Before Telegram Message");
                            sendTelegramMessage("WatchDog - Try to Restart MQTT Client");
                            System.out.println("WatchDog - Try to Restart MQTT Client - After Telegram Message");
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                       
                        watchDogDontSendTelegram = true;
                        System.out.println("WatchDog - Try to Restart MQTT Client - Before mqttConnect");
                        mqttConnect();
                        System.out.println("WatchDog - Try to Restart MQTT Client - After mqttConnect");
                        watchDogDontSendTelegram = false;
                    }
                   
                    // Set last Status (received messages)
                    watchDogCounterMQTT = messagesReceived;
                    watchDogCounterLH   = messagesSendLastHeard;
                   
                    labelWatchDogMQTT.setText(String.valueOf(watchDogCounterMQTT));
                    labelWatchDogLH.setText(String.valueOf(watchDogCounterLH));
                }
            }
        };
       
        this.timerTS12.scheduleAtFixedRate(this.timerTask, 0, 1000);
    }

nicht über das Boolean "watchDogDontSendTelegram" wundern, das hat seinen Sinn. ^^

Als MQTT Client wird Paho mqttv3_1.2.0 verwendet

So schaut der Client aus der die Daten empfängt, ich habe lediglich die URL und die Topics geändert,
Java:
private void mqttConnect() {
    mqttDisConnect();
   
    String broker       = "tcp://url:1883";
    String clientId     = "JavaMQTT" + String.valueOf(System.currentTimeMillis()); // .generateClientId ();;
    MemoryPersistence persistence = new MemoryPersistence();
   
    try {
        mqttClient = new MqttClient(broker, clientId, persistence);
        MqttConnectOptions connOpts = new MqttConnectOptions();
                           connOpts.setCleanSession(true);
                           connOpts.setAutomaticReconnect(true);
                           connOpts.setMaxInflight(2500);
                          
        System.out.println("Connecting to broker: " + broker);
       
        mqttClient.setCallback(new MqttCallback() {
            @Override
            public void connectionLost(Throwable throwable) {
                System.out.println("# Connection Lost Start #####################################");
                System.out.println("# Connection lost to broker: " + broker);
                System.out.println(throwable.getCause());
                throwable.printStackTrace();
                System.out.println("# Connection Lost End ####################################");
               
                lblStatus.setText("Lost");
                lblStatus.setForeground(Color.RED);
               
                try {
                    sendTelegramMessage("MQTT Client - Connection LOST"); // Das ist nur für die Benachrichtigung gedacht
                    mqttSendMsgToWS("{ \"Event\" : \"LOST\",  \"Message\" : \"Connection to Server lost - Reconnect in some seconds\" }", "service"); // Das ist nur für die Benachrichtigung gedacht
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                } catch (JSONException e) {

                    e.printStackTrace();
                }
            }
     
            @Override
            public void messageArrived(String t, MqttMessage m) {
                int iiii = m.toString().getBytes().length;
                setReceivedBytes(iiii);
                try {
                    handleMqttAnswer(t, m);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
     
            @Override
            public void deliveryComplete(IMqttDeliveryToken arg0) {
                // TODO Auto-generated method stub
               
            }
        });
       
       
        mqttClient.connect(connOpts);
       
        mqttClient.subscribe("topic0/#", 0);
        mqttClient.subscribe("topic1/#", 2);
        mqttClient.subscribe("topic2/#", 2);
       
        this.lblStatus.setText("Started");
        this.lblStatus.setForeground(new Color(0, 128, 0));
       
        sendTelegramMessage("MQTT Client started"); // Das ist nur für die Benachrichtigung gedacht
        mqttSendMsgToWS("{ \"Event\" : \"START\",  \"Message\" : \"Connected to Server\" }", "service"); // Das ist nur für die Benachrichtigung gedacht
    } catch(MqttException me) {
        System.out.println("# MqttException Start #####################################");
        System.out.println("reason "     + me.getReasonCode());
        System.out.println("msg "        + me.getMessage());
        System.out.println("loc "        + me.getLocalizedMessage());
        System.out.println("cause "        + me.getCause());
        System.out.println("excep "        + me);
        me.printStackTrace();
        System.out.println("# MqttException End #####################################");
    } catch (Exception e) {
        e.printStackTrace();
    }
}


der Client der die Daten sendet schaut ähnlich aus nur halt ohne Topic Subsciption, auchhier habe ich nur die Zugangsdaten und die URL geändert

Java:
private void mqttConnectRR() {
    String broker       = "tcp://url:1883";
    String clientId     = "JavaMQTTforRR" + String.valueOf(System.currentTimeMillis()); // .generateClientId ();;
    MemoryPersistence persistence = new MemoryPersistence();
   
    try {
        mqttClientWS = new MqttClient(broker, clientId, persistence);
        MqttConnectOptions connOpts = new MqttConnectOptions();
                           connOpts.setCleanSession(true);
                           connOpts.setAutomaticReconnect(true);
                           connOpts.setUserName("meinUsername");
                           connOpts.setPassword("meinPasswort".toCharArray());
                           connOpts.setMaxInflight(2500);
                          
        System.out.println("Connecting to broker WS: " + broker);
       
        mqttClientWS.setCallback(new MqttCallback() {
            @Override
            public void connectionLost(Throwable throwable) {
                System.out.println("# WS Connection Lost Start #####################################");
                System.out.println("# WS Connection lost to broker: " + broker);
                System.out.println(throwable.getCause());
                throwable.printStackTrace();
                System.out.println("# WS Connection Lost End ####################################");
               
                lblStopped.setText("Lost");
                lblStopped.setForeground(Color.RED);
               
                wsAssumedStarted = false;
               
                try {
                    sendTelegramMessage("Last Heard Server - Connection Lost");
                    mqttSendMsgToWS("{ \"Event\" : \"LOST\",  \"Message\" : \"Connection to RR Server lost - Reconnect in some seconds\" }", "service");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
     
            @Override
            public void messageArrived(String t, MqttMessage m) {
                /*
                Currently there are no messages send to this system
                */
            }
     
            @Override
            public void deliveryComplete(IMqttDeliveryToken arg0) {
                // TODO Auto-generated method stub
               
            }
        });
       
        mqttClientWS.connect(connOpts);
        sendTelegramMessage("Last Heard Server started");
        mqttSendMsgToWS("{ \"Event\" : \"START\",  \"Message\" : \"Connected to RR Server\" }", "service");
        this.lblStopped.setText("Started");
        this.lblStopped.setForeground(new Color(0, 128, 0));
    } catch(MqttException me) {
        System.out.println("# WS MqttException Start #####################################");
        System.out.println("reason "     + me.getReasonCode());
        System.out.println("msg "        + me.getMessage());
        System.out.println("loc "        + me.getLocalizedMessage());
        System.out.println("cause "        + me.getCause());
        System.out.println("excep "        + me);
        me.printStackTrace();
        System.out.println("# MqttException End #####################################");
    } catch (Exception e) {
        e.printStackTrace();
    }
}



Ein erster Ansatzpunkt vorher war
MqttConnectOptions.setMaxInflight() gewesen welches per default auf 10 steht und ich deswegen öfters mal Hänger hatte, also habe ich es testweise auf setMaxInflight(2500) geändert (in einer Anleitung stand was von 64000 was wohl geht)

Danach ist dann erst mal alles stabil gelaufen

nebenbei bemerkt habe ich 2 ExecuterService
Java:
    private ExecutorService executor   = Executors.newFixedThreadPool(10);
    private ExecutorService executorLH = Executors.newFixedThreadPool(15);

Der 10er Pol ist dafür da Aufgaben abzuarbeiten, also Anfragen welche über MQTT vom Sender kommen. Das sind aber nicht viele, evtl so 5 in der Minute, manchmal auch Minuten lang nichts. Die Aufgaben selbst dauern nur ca 1 Sekunde.

Der 15er Pool ist für das weiter senden der Nachrichten per QOS2 an den anderen Broker, das sind so 2-10 Nachrichten pro Sekunde

Hier bei MQTT liegt eine meiner Vermutungen das dort irgendwie der nennen wir es mal Cache nicht gelöscht wird durch den Garbage Collector oder ich mache was falsch. Irgendwo hatte ich auch mal gelesen das es öfters wohl Probleme mit QOS 2 Messages geben soll.

Da ja wie man sieht doch ganz schon was an Nachrichten rein kommt und einige auch doppelt mache ich einen Duplicatecheck welcher ungefähr 1/3 der Nachrichten raus filtert so das sie nicht weiter bearbeitet werden müssen geschweige denn weiter gesendet werden.

Das Ganze mache ich mit einer Arraylist

Java:
    public boolean checkIfDoubleData (ArrayList<DoubleData> doubleDataArrayList, String message) {
        for(DoubleData dd : doubleDataArrayList) {
            if(dd.getContent().equals(message)) return true;
        }
        return false;
    }

Hierbei ist message einfach nur die MqttMessage.getPayload()
ob das jetzt eine tolle Lösung ist weiß ich nicht, pro Sekunde kommen ca 300 Nachrichten rein und nach 3 Sekunden lösche ich die alten Einträge in der Arraylist

Java:
    public ArrayList<DoubleData> removeExpiredDoubleData(ArrayList<DoubleData> doubleDataArrayList) {
        //int before = doubleDataArrayList.size();
        doubleDataArrayList.removeIf(data -> data.getTimestamp() <= (getUnixTime() - 3));
        //int after = doubleDataArrayList.size();
       
        //System.out.println(before + " --> " + after);
       
        return doubleDataArrayList;
    }

Hier noch das DoubleData Objekt
Java:
public class DoubleData {

    private String content = "";
    private int timestamp  = 0;
   
    public DoubleData(int timestamp, String content) {
        setContent(content);
        setTimestamp(timestamp);
    }

    /**
     * @return the content
     */
    public String getContent() {
        return content;
    }

    /**
     * @param content the content to set
     */
    public void setContent(String content) {
        this.content = content;
    }

    /**
     * @return the timestamp
     */
    public int getTimestamp() {
        return timestamp;
    }

    /**
     * @param timestamp the timestamp to set
     */
    public void setTimestamp(int timestamp) {
        this.timestamp = timestamp;
    }
   
}

Hier wäre ein weiter Ansatzpunkt von mir das dort der Garbage Collector nicht aufräumt oder ich was falsch gemacht habe.

Im Endeffekt ist ein ganz ganz leichter Anstieg vom RAM erwartet da sobald ein neuer User in Datenstrom auf taucht wird dafür ein Objekt angelegt und dieses dann in eine Arrayliste gepackt und wenn der User wieder aktiv ist wird dieses Objekt aktualisiert,

Aktuell sind das ca 11.000 User, wenn ich die ArrayList serilized speichere ist die Datei ca 1,4 MB groß, das ganze mache ich so mittels stream wobei ich hier jetzt auch nicht weiß ob Stream da gut ist oder nicht, dachte mir zumindest das bei der Anzahl an Einträgen Stream effectiver ist

Java:
public ActiveCalls checkIfCallSignIsCachedBase(String id){
    List<ActiveCalls> result = this.callDataArrayList.stream()
            .filter(line -> line.getId().equals(id))
            .distinct()
            .sorted(Comparator.comparing(ActiveCalls::getCallSign))
            .collect(Collectors.toList());
           
    for (ActiveCalls entry : result){
        if(entry.getId().equals(id)){
            return entry;
        }
    }
   
    return null;
}

und
Java:
ActiveCalls activeCall = checkIfCallSignIsCachedBase(sourceID);
if(activeCall == null) {
    // new entry
    ActiveCalls newActiveCall = new ActiveCalls("unwichtig");
    callDataArrayList.add(newActiveCall);
}else {
    // update entry
    // unwichtig
}

hier sehe ich eigentlich kein Potential für ein Memeory Problem

Also was meint ihr ? Habe ich was falsch gemacht was dazu führen kann ? Oder ist es es evtl ein Problem mit dem Paho Clienten oder mit dem Java Garbage Control ?
 

thecain

Top Contributor
Schau dir einen memory dump an oder schau auf die Auslastung z.b. mit visual vm. Ich glaube kaum das mit den Code Stücken das jemand erraten kann
 

Nisbo

Bekanntes Mitglied
Danke für die Antwort

Beim Code ging es ums Prinzip ob da evtl was falsch gemacht wurde, evtl gibt es ja Methoden zum clearen vom MQTT Cache usw oder das Artefakte in der ArrayList bleiben, zwar unlogisch aber man weiß ja nie.

Schau dir einen memory dump an oder schau auf die Auslastung z.b. mit visual vm.
Das ist für mich leider "Bahnhof", also noch nie gemacht, k.A. wie es geht muss mal gucken ob ich dazu was ergoogeln kann :)

EDIT:

How to Get and Run VisualVM
The good news here, you actually don’t need to do anything, it is already available in the JDK bin directory. It’s available after JDK 1.6 update 7. Once you are in the bin directory of JDK, you will find jVisualVM.exe; just click on it, and the application starts up.

jVisualVM.exe ist da (jre1.8.0_151\bin) leider nicht drin, kann sie auch mit der Windows Suche nicht finden

EDIT2: Sehe gerade JDK, ich habe nur JDE installiert
 
Zuletzt bearbeitet:

Nisbo

Bekanntes Mitglied
Bei Heap habe ich einen Sägezahn alle 30 Sekunden, das wird dann wohl der GC sein der aufräumt ?

Aber ich sehe gerade wenn ich eine der Abfragen mache wozu das Programm gemacht wurde geht die Thread Anzahl hoch aber nicht mehr komplett runter
 

Anhänge

  • Screenshot_628.jpg
    Screenshot_628.jpg
    108,6 KB · Aufrufe: 27

Nisbo

Bekanntes Mitglied
Das Visual VM ist echt nett :)

Was mich jetzt wundert sind die "Park" Threads, die Doku
https://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/LockSupport.html#park()
hilft mir da auch nicht weiter

Im Bild sieht man das ganz gut, da wo die "Treppen" drin sind habe ich den Clienten neu gestartet, also das was z.b. der WatchDog auch macht.

Ansonsten, jetzt außerhalb von Eclipse habe ich keinen Anstieg vom RAM mehr drin, geht mal hoch und dann wieder runter

Java:
private MqttClient mqttClientWS = null;

und so beende ich den Clienten

Java:
    private void mqttDisConnectRR() {
        try {
            System.out.println("Disconnecting from broker WS");
            if(mqttClientWS != null && mqttClientWS.isConnected()) mqttClientWS.disconnect();
        } catch (MqttException e) {
            System.out.println("MqttException while Disconnecting from broker RR");
            e.printStackTrace();
        }
    }

Wenn ich wieder neu starte dann wird mqttClientWS wieder "benutzt"
nur warum daraus ein PARK Thread wird verstehe ich nicht, oder ist das normal ?


EDIT: OK man muss wohl noch ein .close() auf den MQTTClient machen dann passt jetzt alles :)
 

Anhänge

  • Screenshot_629.jpg
    Screenshot_629.jpg
    287,9 KB · Aufrufe: 35
Zuletzt bearbeitet:

JuKu

Top Contributor
Also dein Problem ist scheinbar, dass der HEAP Speicher überläuft, also voll ist.

Bevor ich tiefer in die Materie gehe, noch einwas vorneweg:
Java darf per Default nicht deinen ganzen RAM verwenden, das kannst du aber mit entsprechenden Flags ändern.
Dann hat sich das Problem evtl. bereits gelöst.

Der nächste Punkt ist, dass du aufgrund der hohen Nachrichten Anzahl auch vermutlich viele Objekte und somit viel GC Pressure erzeugst. Der GC läuft nicht dauerhaft, sondern immer mal ab und zu, sonst wäre dein Programm ziemlich langsam. Wenn du aber schneller Speicher allozierst, als der GC freigeben kann, läuft der logischerweise irgendwann über.
Du müsstest dann herausfinden, wo du ständig Objekte erzeugst und ob du irgendwo einsparen kannst (z.B. durch Poolen von Objekten).
Und über VisualVM bekommst du das heraus.
 

Nisbo

Bekanntes Mitglied
VisualVM ist der Hammer, warum kannte ich das nur vorher noch nicht :D
Habe mein Problem inzwischen gelöst, hatte einmal PARK Threads gehabt da ich Paho MQTT Verbindungen disconnected hatte aber nicht ge-closed und dann chache ich noch einen teil der Nachrichten und lösche sie sobald die Nachricht beendet ist (in dem Fall wenn jemand aufhört zu sprechen) hierbei hatte ich aber vergessen was zu löschen und man konnte gut sehen wie sich der Max Heap immer mal um 2 MB erhöht hat.
 

Anhänge

  • Screenshot_632.jpg
    Screenshot_632.jpg
    117 KB · Aufrufe: 32

mrBrown

Super-Moderator
Mitarbeiter
Stimmt, kommt auf den Use Case drauf an. Gerade in der Spieleentwicklung ist es aber sehr beliebt.
Beliebt != sinnvoll ;)

Grad bei so kleinen und kurzlebigen Dingen wie z.B. Vektoren verursacht das schnell mehr Overhead.
Langlebige Objekte kosten mehr GC-Zeit als kurzlebige, die einfach ignoriert werden können, und das Pooling kostet tendenziell mehr als das alloziieren eines neuen Objekts - wobei natürlich bei mehr Objekten der GC öfter laufen muss. Zusätzlich kann bei der nicht-Pool-Variante tendenziell mehr optimiert werden, bietet also gleich noch mehr Potential für die Zukunft ;)
 

JuKu

Top Contributor
In der Spieleentwicklung kommt es aber eher darauf an, die GC Cycles so gering wie möglich zu halten und nicht zwingend, wie hoch der RAM Verbrauch ist. Bei 60 FPS hat man für einen Frame 16ms, wenn jetzt aber der GC ständig dazwischen springt und 16ms braucht, bedeutet das schon ein Frame Drop, denn der GC unterbricht das Programm (er pausiert es ja quasi während der Ausführung), was sich in einem Ruckeln bemerkbar macht. Das Ziel ist es also quasi zu verhindern, dass der GC oft läuft und nicht, dass man wenig RAM verbraucht. Also dass das Spiel möglichst flüssig läuft.

Je nach Garbage Collector gibt es ja verschiedene Zonen und die neueren Zonen werden bei jedem Durchlauf aufgeräumt, während die älteren nur alle x Durchläufe (z.B. bei Java 7 glaube alle 6 - 10 Cycles) durchlaufen werden. Es ist also für die Spieleentwicklung günstiger, Objekte in diesen alten Zonen zu "parken", als in den neuen, bei welchen der GC oft anspringt. Zumindest wurde mir das so von Leuten erklärt, die bei BlueByte Networking (in Java) für MMOs gemacht haben.
Das ganze wird mit Java 10 aber schon wieder über Bord geworfen, weil mit Java 10 schon wieder ein neuer GC eingeführt wird, der teilweile nicht mal mehr zwingend das Programm unterbrechen muss. :D
 

mrBrown

Super-Moderator
Mitarbeiter
In der Spieleentwicklung kommt es aber eher darauf an, die GC Cycles so gering wie möglich zu halten und nicht zwingend, wie hoch der RAM Verbrauch ist. Bei 60 FPS hat man für einen Frame 16ms, wenn jetzt aber der GC ständig dazwischen springt und 16ms braucht, bedeutet das schon ein Frame Drop, denn der GC unterbricht das Programm (er pausiert es ja quasi während der Ausführung), was sich in einem Ruckeln bemerkbar macht. Das Ziel ist es also quasi zu verhindern, dass der GC oft läuft und nicht, dass man wenig RAM verbraucht. Also dass das Spiel möglichst flüssig läuft.
RAM und GC hängen untrennbar zusammen, der GC wird ua vom Ram-Verbrauch getriggert...


Je nach Garbage Collector gibt es ja verschiedene Zonen und die neueren Zonen werden bei jedem Durchlauf aufgeräumt, während die älteren nur alle x Durchläufe (z.B. bei Java 7 glaube alle 6 - 10 Cycles) durchlaufen werden. Es ist also für die Spieleentwicklung günstiger, Objekte in diesen alten Zonen zu "parken", als in den neuen, bei welchen der GC oft anspringt. Zumindest wurde mir das so von Leuten erklärt, die bei BlueByte Networking (in Java) für MMOs gemacht haben.
Jein, da werden grad Dinge vermischt - Die Häufigkeit des Anspringens und die Dauer eines Aufräumens.
Arbeit für den GC (=längeres Aufräumen) machen nur lebende Objekte, alle Toten Objekte werden vom GC nicht beachtet (sie werden implizit wie freier Speicher behandelt).
Objekte, die also üblicherweise nur zwischen zwei GC Aufrufen leben, beeinträchtigen die Dauer des Aufräumens also nicht.
Langlebige Objekte (also gepool'te) müssen bei jedem Aufräumen, bis sie in der "alten Zone" landen, beachtet werden, und danach bei jedem Aufräumen der alten Zone, zusätzlich kommt der Overhead des Pools dazu (der ein vielfaches eines new betragen dürfte).

Dazu kommt eben der Verlust von Optimierungen und das vielfach schlechtere Design. Beliebt für Pooling sind ja grad auch so Dinge wie z.B. Vektoren.
Sauber umgesetzt hätte man einen immutable "Value-Objects", der größtenteils innerhalb von Methoden verwendet wird, und damit wunderbar optimiert werden kann( z.B. dank Escape-Analysis überhaupt nicht auf dem Heap angelegt werden muss).

gepool't ist das Design gleich Größenordnungen schlechter (Mutable Datentypen, bei jeder Verwendung den Pool beachten, ...) und es können kaum noch Optimierungen greifen.


Mich würden aber mal Benchmarks dazu interessieren...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
E Wie Java Heap Space vergrößern? Allgemeine Java-Themen 3
A Heap-Sort Allgemeine Java-Themen 2
L Java OutOfMemoryError Java heap space Allgemeine Java-Themen 3
H Änderung im maximalen heap space unter Windows 7 ?! Allgemeine Java-Themen 5
D Grundsätzliche Fragen zum Heap Space Allgemeine Java-Themen 12
D Datentypen Cache Images Heap Space Error Allgemeine Java-Themen 7
Thallius Wie mache ich eine Java App mit Icon startbar die mehr Heap Speicher braucht? Allgemeine Java-Themen 3
T jstat Heap(Size/Usage) PermGen(Size/Used) vs JVisual VM Allgemeine Java-Themen 2
H Frage wegen Heap-Speicher Allgemeine Java-Themen 2
L java.lang.OutOfMemoryError: Java heap space Allgemeine Java-Themen 10
R Referenzen im Heap anzeigen Allgemeine Java-Themen 3
S Compiler-Fehler Heap space! Allgemeine Java-Themen 2
V Java Heap Size -Xmx1024m reicht nicht! Allgemeine Java-Themen 14
C Method Area, Stack, Heap Allgemeine Java-Themen 7
A Umgebungsvariable Kann Heap Space nicht vergrößern Allgemeine Java-Themen 6
T Objekt 2x deserialisieren, aber nur 1x im Heap haben? Allgemeine Java-Themen 4
M *.jar >>> *.exe und "heap size" Allgemeine Java-Themen 11
E Konfigurieren des Java Heap-Spaces Allgemeine Java-Themen 5
D Java Heap error trotz anpassungen mit -xmx Allgemeine Java-Themen 4
Guybrush Threepwood Heap-Space "überwinden" Allgemeine Java-Themen 2
O Problem mit dem Heap Space (Speicherüberlauf) Allgemeine Java-Themen 12
S Java heap space zu klein? Allgemeine Java-Themen 6
A Heap in Jcreator erhöhen? Allgemeine Java-Themen 5
P Java Heap Size feststellen Allgemeine Java-Themen 6
K Heap-Volllaufen bei ArrayList<Integer> Allgemeine Java-Themen 9
B Java Heap Space Allgemeine Java-Themen 5
byte JVM Maximum Heap (Windows XP Prof. 32bit) Allgemeine Java-Themen 4
A Wie am besten Daten auslagern um heap zu schonen Allgemeine Java-Themen 4
G Probleme mit dem Java heap Allgemeine Java-Themen 14
E Heap und Comparable (warning: [unchecked] unchecked cast) Allgemeine Java-Themen 2
A OutOfMemoryError: Java heap space Allgemeine Java-Themen 11
kb22 CMS mit großen Dateien (heap problem) Allgemeine Java-Themen 3
hdi Heap Sapce Error bei sehr großem String Allgemeine Java-Themen 5
P not enough space for object heap - Trotz mehr RAM? Allgemeine Java-Themen 6
I Java heap space Allgemeine Java-Themen 3
K Erhöhung Java Heap Space in Netbeans 6.5 - funktioniert nicht oder bringt nichts? Allgemeine Java-Themen 1
S Java Heap Dump erstellen Allgemeine Java-Themen 1
T zu Beginn der main: Heap space ermitteln und hochsetzen Allgemeine Java-Themen 11
K OutOfMemoryError: Java heap space troz -Xms1024m Allgemeine Java-Themen 2
O viele Datensätze aus Datenbank - Java Heap Space - Excepion Allgemeine Java-Themen 25
V Java heap space Problem Allgemeine Java-Themen 8
V Wieso Heap Space Problem? Allgemeine Java-Themen 14
Saxony ANT, ProGuard und Java heap space Allgemeine Java-Themen 8
MQue Heap erhöhen Allgemeine Java-Themen 8
V fehlermeldung heap space, endlosschleife??? Allgemeine Java-Themen 4
M Heap Speicher voll bei spezieller Resize Methode Allgemeine Java-Themen 5
P Java Heap Space Allgemeine Java-Themen 11
P Dump von JavaWS Heap Allgemeine Java-Themen 4
P Java heap Allgemeine Java-Themen 5
F OutOfMemoryError: Java heap space - Speicher verändern Allgemeine Java-Themen 8
P Java Heap Space Exception Allgemeine Java-Themen 30
M JVM Non-Heap läuft voll Allgemeine Java-Themen 4
MQue Java Heap space Probleme Allgemeine Java-Themen 26
T Langsames Laden von Bildern und Heap Exception Allgemeine Java-Themen 7
B Erkennen welche Objekte den Heap verbrauchen? Allgemeine Java-Themen 2
Y PDF Report mit Tomcat Heap Space Problem Allgemeine Java-Themen 9
J java Thread java.lang.OutOfMemoryError: Java heap space Allgemeine Java-Themen 7
G Error: java.lang.OutOfMemoryError: Java heap space Allgemeine Java-Themen 2
G Zum tausendsten Mal Heap Size Allgemeine Java-Themen 5
P out of memory -> heap wächst und wächst Allgemeine Java-Themen 7
S Heap dump Allgemeine Java-Themen 3
F Heap Overflow Allgemeine Java-Themen 9
M Aktuellen heap space ermitteln? Allgemeine Java-Themen 2
G Wird bei RAM-Mangel für Java Heap Space geswappt? Allgemeine Java-Themen 34
B Der Heap Space, ich weiß nicht mehr weiter! Allgemeine Java-Themen 15
H java heap space (outofmemory error) Allgemeine Java-Themen 3
D statisch heap size erhöhen Allgemeine Java-Themen 4
F java.lang.OutOfMemoryError: Java heap space Allgemeine Java-Themen 22
L Häufigkeit der Werte in Datei zählen! Heap Space beschränkt! Allgemeine Java-Themen 31
V Serialisierungsproblem bzw. Heap Problem Allgemeine Java-Themen 13
C Java heap Space, aber wie wegkriegen? Allgemeine Java-Themen 3
P Jave Heap Size und ObjectStreams.ein java bug ? Allgemeine Java-Themen 5
welterde Heap Überlauf Allgemeine Java-Themen 2
F Verfügbaren Heap-Speicher setzen Allgemeine Java-Themen 2
N Speicher Problem bei grossem Heap Allgemeine Java-Themen 15
M lauffähiges Java Program auf Web Space Allgemeine Java-Themen 2
C JTextPane + HTMLEditorKit withe space problem Allgemeine Java-Themen 0
D OutOfMemoryError:Java hep space Allgemeine Java-Themen 7

Ähnliche Java Themen

Neue Themen


Oben