Frage

Wie optimieren Sie die Verwendung einer Anwendung mit einer Menge (Millionen) langlebiger Objekte? (Big Cache, viele Datensätze aus einem DB laden)

  • Verwenden Sie den richtigen Datentyp
    • Vermeiden Sie Java.lang.String, um andere Datentypen darzustellen
  • Vermeiden Sie doppelte Objekte
    • Verwenden Sie Enums, wenn die Werte im Voraus bekannt sind
    • Verwenden Sie Objektpools
    • String.Intern () (gute Idee?)
  • Laden/behalten Sie nur die Objekte, die Sie benötigen

Ich suche allgemeine Programmier- oder Java -spezifische Antworten. Kein funky Compiler -Schalter.

Bearbeiten:

Optimieren Sie die Speicherdarstellung eines Pojo, das Millionen von Zeiten im Haufen erscheinen kann.

Anwendungsfälle

  • Laden Sie eine riesige CSV -Datei in Speicher (in Pojos konvertiert)
  • Verwenden Sie Hibernate, um Millionen von Datensätzen aus einer Datenbank abzurufen

Wiederaufnahme der Antworten:

  • Verwenden Sie das Fliegengewichtsmuster
  • Kopieren Sie auf Schreiben
  • Ist es effizienter, 3 Arrays (oder eine andere Datenstruktur) der Größe 10 m zu haben, anstatt 10m -Objekte mit 3 Eigenschaften zu laden? (Könnte ein Schmerz sein, Daten zu manipulieren, aber wenn Sie wirklich kurz das Gedächtnis haben ...)
War es hilfreich?

Lösung

Sie sagen nicht, welche Art von Objekten Sie speichern möchten. Es ist daher ein wenig schwierig, detaillierte Ratschläge zu geben. Einige (nicht exklusive) Ansätze in keiner bestimmten Reihenfolge sind:

  • Verwenden ein Fliegengewichtsmuster woimmer möglich.
  • Zwischen Disc. Es gibtzahlreich Cache -Lösungen für Java.
  • Es gibt einige Debatten darüber, ob String.intern eine gute Idee ist. Sehenhier für eine Frage re. String.Intern () und die Debatte um seine Eignung.
  • Gebrauch machen von Sanft oder schwachVerweise auf Speicherdaten, die Sie auf Bedarf neu erstellen/neu laden können. Sehenhier So verwenden Sie weiche Referenzen mit Caching -Techniken.

Wenn Sie mehr über die Interna und die Lebensdauer der von Ihnen speichernden Objekte wissen, würde dies zu einer detaillierteren Antwort führen.

Andere Tipps

Ich schlage vor, Sie verwenden einen Speicherprofiler, sehen Sie, wo der Speicher verzehrt wird, und optimieren Sie dies. Ohne quantitative Informationen könnten Sie am Ende die Sache ändern, die entweder keine Auswirkungen haben oder die Dinge tatsächlich verschlimmern.

Sie können sehen, wie Sie die Darstellung Ihrer Daten ändern können, insbesondere wenn Ihre Objekte klein sind. Sie können beispielsweise eine Datenentelle als eine Reihe von Spalten mit Objektarrays für jede Spalte darstellen und nicht als ein Objekt pro Zeile. Dies kann für jedes Objekt eine erhebliche Menge an Overhead sparen, wenn Sie keine einzelne Zeile darstellen müssen. zB eine Tabelle mit 12 Spalten und 10.000.000 Zeilen könnten 12 Objekte (eine pro Spalte) anstelle von 10 Millionen (eine pro Zeile) verwenden

Stellen Sie sicher, dass Ihr Objektmodell eine gute Normalisierung des Objektmodells gewährleistet, keine Werte.

Ähm, und wenn es nur Millionen von Objekten sind, denke ich, würde ich einfach ein anständiges 64 -Bit -VM und viel Ram machen;)

Normale "Profiler" helfen Ihnen nicht viel, da Sie einen Überblick über alle Ihre "Live" -Objekte benötigen. Sie benötigen einen Heap -Dump -Analysator. Ich empfehle das Eclipse Memory Analyzer.

Überprüfen Sie, ob doppelte Objekte beginnend mit Saiten. Überprüfen Sie, ob Sie Muster wie Flightweight, Copyonwrite, Lazy Initialisierung anwenden können (Google ist Ihr Freund).

Schauen Sie sich diese Präsentation an, die hier verknüpft ist. Es legt die Speicherverwendung von gemeinsamem Java -Objekt und Primitiven fest und hilft Ihnen zu verstehen, wohin das zusätzliche Speicher führt.

Aufbau von speichereffizienten Java-Anwendungen: Praktiken und Herausforderungen

Sie können einfach weniger Objekte im Speicher speichern. :) Verwenden Sie einen Cache, der sich umscheiben oder Terrakotta verwenden, um Ihren Haufen (was virtuell) zu gruppieren, sodass nicht verwendete Teile aus dem Gedächtnis geraten und transparent wieder in Einsatz geraten werden können.

Ich möchte etwas hinzufügen, dem Punkt Peter Alredy gemacht hat (kann seine Antwort nicht kommentieren :() Es ist immer besser, einen Speicherprofiler zu verwenden (überprüfen Java Memory Profiler) als von Intution zu gehen.80% der Zeit ist es Routine, die wir ignorieren, hat ein Problem damit. Auch Sammlungsklassen sind anfälliger für Speicherlecks.

Wenn Sie Millionen von Ganzzahlen und Schwimmern usw. haben, prüfen Sie, ob Ihre Algorithmen die Daten in Arrays von Primitiven darstellen. Das bedeutet weniger Referenzen und niedrigere CPU -Kosten für jede Müllsammlung.

Eine schicke: Halten Sie die meisten Daten im RAM komprimiert. Erweitern Sie nur den aktuellen Arbeitssatz. Wenn Ihre Daten eine gute Lokalität haben, die gut funktionieren kann.

Verwenden Sie bessere Datenstrukturen. Die Standardkollektionen in Java sind eher Speicherintensiv.

Was ist eine bessere Datenstruktur

  • Wenn Sie sich die Quelle für die Sammlungen ansehen, werden Sie feststellen, dass Sie, wenn Sie sich auf die Sammlung einschränken, Platz pro Element sparen können.
  • Die Art und Weise, wie das Sammel wächst, ist für große Sammlungen nicht gut. Zu viel kopieren. Für große Sammlungen benötigen Sie einen blockbasierten Algorithmus wie BTree.

Verbringen Sie einige Zeit damit, sich kennenzulernen und das abzustimmen VM -Befehlszeilenoptionen, insbesondere diejenigen, die sich mit der Müllsammlung befassen. Dies ändert zwar den von Ihren Objekten verwendeten Speicher nicht, aber es kann einen großen Einfluss auf die Leistung mit speicherintensiver Apps auf Maschinen mit viel RAM haben.

  1. Assign null Wert für alle variables welche sind no longer Gebraucht. Daher make it available for Garbage collection.
  2. De-reference the collections Sobald die Verwendung beendet ist, wird GC diese sonst nicht fegen.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top