Java Speicher-Overhead
Ich würde Sie gerne Fragen, wie etwa Speicher-Overhead in java,
Ich habe eine große ArrayList (61,770 Elemente), und versuchen zu berechnen, wie viel Speicher, die jedem Element (Zählung das Objekt und seine ArrayList-Eintrag),
durch Profilierung der app bekomme ich dass, nachdem alle Daten geladen, wird der heap nimmt ~ 25 MB.
wenn die ArrayList hat nur 2 Elemente, die die heap-dauert ~1 MB , also etwa so:
(24*1024*1024)/61,768 = 407 bytes.
jedoch, wenn ich die Anzahl der Felder der einzelnen Objekte, bekomme ich 148 bytes(nicht einschließlich die ArrayList, und wenn int=4 float=4,reference=4), ich bin neugierig zu wissen, wo es all diese zusätzlichen bytes kamen...
ich kann mir vorstellen, dass da die Objekte Speichere ich in der ArrayList implementieren eine Schnittstelle, die Sie speichern zusätzliche Werte, vielleicht die VM speichert eine 4byte-Funktion Zeiger für jede implementierte Methode?
die Schnittstelle, die Sie implementieren, 20 Funktionen, so dass das ist, 80 bytes mehr insgesamt 228 bytes, die noch nicht in der Nähe der 400 bytes gemessen.
jede mögliche Hilfe würde geschätzt.
wow, danke für all die tollen Antworten.
@Bolo: danke für den link ,mit dieser Klasse, die ich Messen ~350 Byte pro Objekt, so kann ich zumindest bestätigen, die Quelle der großen Arbeitsspeicher.
@Yuval A: danke für diese Präsentation, eine wertvolle Quelle von Informationen.
@Ukko: Punkt hingewiesen.
@Jayan: jetzt NetBeans profiler gibt mir Fehler, wenn ich versuche heap-dump, wird versuchen Sie es später erneut.
- Diese Artikel können für Sie nützlich sein: javaworld.com/javaworld/javatips/jw-javatip130.html
- Wenn Sie beginnen mit new ArrayList(61770) anstelle von, zum Beispiel, new ArrayList() und dann lassen Sie es automatisch die Größe ändern, Sie würde auch einen unterschiedlichen Aufwand. Haben Sie die richtige Größe, bevor Sie Speicherauslastung?
- 61 770 ist nicht groß 🙂 ich habe eine HashMap<Integer,Integer> so groß, dass Sie bringen die meisten Systeme in die Knie zu zwingen... Das ist der Grund, warum ich ersetzte Sie mit Fundgrube ist TIntIntHashMap, die sind einfach so viel mehr Speicher/Geschwindigkeit-effizient 🙂 Ach, es funktioniert nur mit primitiven :-/
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind diese Ergebnisse nicht überraschend. Die JVM fügt enorme Mengen an overhead für jedes Objekt.
Ungefähr das doppelte der erwarteten Größe für ein einzelnes Objekt ist, aufgrund von JVM-Speicher-overhead, ist nicht ungewöhnlich.
Diese Präsentation hat eine wunderbare, in die Tiefe gehende Erklärung und überblick über die verschiedenen Daten-Struktur Speicherverbrauch in Java.
Einer ArrayList ist meist größer als die Anzahl der Elemente. Verwenden
getCapacity()
um die aktuelle Größe des zugrunde liegenden array.Ein großes problem mit deinem Ansatz ist die Interaktion mit dem garbage collector. Im Grunde macht sich jeder testen, wie Sie vorgeschlagen haben, völlig undurchsichtig von außen.
Als ein Gedanken-experiment, wenn Sie wollte, dies zu tun, sollten Sie
Nachdem alle, und ein bisschen Mathematik werden Sie näher, aber immer noch nicht richtig. Die einzige wirkliche Lösung ist, um tatsächlich zu Fragen der Umsetzung, wie andere Leute erwähnt haben. Oder Zahl es sich aus der Kenntnis von der Umsetzung.
Speicher verbraucht arraylist ist ein wenig vage.
Einen heap dump des Prozesses an geeigneten stellen - nachdem die Werte sind komplett belegt. Dann verwenden Sie tools wie memory analyser (von eclipse).
Füllen Sie finden seicht und beibehalten Speichergrößen.
Als eine Randnotiz, da Sie genau wissen, wie viele Objekte in deiner ArrayList, warum nicht einfach ein array[]? Wird die Anzahl der Objekte in es ändern?