Ich habe eine Bibliothek in C geschrieben, die viel Speicher verbraucht (Millionen von kleinen Blöcken). Ich habe ein c-Programm geschrieben, das diese Bibliothek verwendet. Und ich habe ein Java-Programm geschrieben, das dieselbe Bibliothek verwendet. Das Java-Programm ist eine sehr dünne Schicht um die Bibliothek herum. Grundsätzlich gibt es nur eine native Methode, die aufgerufen wird, die ganze Arbeit erledigt und Stunden später zurückkehrt. Es gibt keine weitere Kommunikation zwischen Java und der nativen Bibliothek über die Java-Aufrufschnittstelle. Es gibt auch keine Java-Objekte, die eine nennenswerte Speichermenge verbrauchen.Warum verwendet eine native Bibliothek 1,5 Mal mehr Speicher, wenn sie von Java verwendet wird, als wenn sie von einem C-Programm unter Linux verwendet wird?
Also sind das c-Programm und das Java-Programm sehr ähnlich. Die gesamte Berechnung/Speicherzuordnung erfolgt innerhalb der nativen Bibliothek. Immer noch. Wenn es ausgeführt wird, verbraucht das c-Programm 3 GB Arbeitsspeicher. Aber das Java-Programm verbraucht 4,3 GB! (VIRT-Menge von oben gemeldet)
Ich überprüfte die Speicherkarte des Java-Prozesses (mit Pmap). Nur 40 MB werden von Bibliotheken verwendet. Daher sind zusätzliche Bibliotheken, die von Java geladen werden, nicht die Ursache.
Hat jemand eine Erklärung für dieses Verhalten?
EDIT: Danke für die Antworten bisher. Um es ein wenig klarer zu machen: Der Java-Code ruft nur die native Bibliothek auf ONCE! Der Java-Heap hat die Standardgröße (vielleicht 60 MB) und wird nicht verwendet (außer für die eine Klasse, die die Hauptmethode enthält, und für die andere Klasse, die die native Bibliothek aufruft).
Die native Bibliotheksmethode ist eine lange laufende und tut viele Mallocs und Freigaben. Fragmentierung ist eine Erklärung, die ich auch an mich selbst dachte. Da jedoch kein Java-Code aktiv ist, sollte das Fragmentierungsverhalten für das Java-Programm und das c-Programm gleich sein. Da es anders ist, nehme ich auch an, dass die verwendeten malloc-Implementierungen unterschiedlich sind, wenn sie im c-Programm oder im Java-Programm ausgeführt werden.
Interessante Beobachtung. Ich hätte dieses Verhalten nicht erwartet. – x4u
Malloc Heap Fragmentierung. Siehe http://stackoverflow.com/a/28935176/166062 –
@LariHotari Während der Grund für diese Frage eine andere war (siehe meine Antwort), hatten wir tatsächlich auch Probleme mit der Fragmentierung. Wir haben es gelöst, indem wir zu alternativen Implementierungen wie tcmalloc, jemalloc oder der malloc-Implementierung von locklessinc gewechselt haben. –