Wie erhalte ich die Größe eines JavaScript-Objekts?
Lesezeit: 8 Minuten
Ich möchte wissen, wie groß ein JavaScript-Objekt ist.
Nehmen Sie die folgende Funktion:
function Marks(){
this.maxMarks = 100;
}
function Student(){
this.firstName = "firstName";
this.lastName = "lastName";
this.marks = new Marks();
}
Jetzt instanziiere ich die student:
var stud = new Student();
damit ich sowas machen kann
stud.firstName = "new Firstname";
alert(stud.firstName);
stud.marks.maxMarks = 200;
usw.
Jetzt die stud Objekt belegt eine gewisse Größe im Speicher. Es hat einige Daten und mehr Objekte.
Wie finde ich heraus, wie viel Speicher die stud Objekt besetzt? So etwas wie ein sizeof() in Javascript? Es wäre wirklich genial, wenn ich es in einem einzigen Funktionsaufruf wie herausfinden könnte sizeof(stud).
Ich habe monatelang im Internet gesucht – konnte es nicht finden (in einigen Foren gefragt – keine Antworten).
Was ist mit der Antwort auf diese Frage: stackoverflow.com/questions/4391575/…
Ich habe den Code in meiner ursprünglichen Antwort umgestaltet. Ich habe die Rekursion entfernt und den Overhead der angenommenen Existenz entfernt.
function roughSizeOfObject( object ) {
var objectList = [];
var stack = [ object ];
var bytes = 0;
while ( stack.length ) {
var value = stack.pop();
if ( typeof value === 'boolean' ) {
bytes += 4;
}
else if ( typeof value === 'string' ) {
bytes += value.length * 2;
}
else if ( typeof value === 'number' ) {
bytes += 8;
}
else if
(
typeof value === 'object'
&& objectList.indexOf( value ) === -1
)
{
objectList.push( value );
for( var i in value ) {
stack.push( value[ i ] );
}
}
}
return bytes;
}
Vielleicht möchten Sie auch an die Objektschlüssel denken
– zupa
24. Januar 2013 um 16:28 Uhr
Jeder, der hier gelandet ist und nach dem kleinsten Typ für die Zwecke falsch/wahr gesucht hat, scheint undefiniert/null zu sein.
– zupa
24. Januar 2013 um 16:32 Uhr
"よんもじ".length ist 4 in Javascript, aber sind Sie sicher, dass es 8 Bytes sind, da Ihr Code es zurückgibt?
Diese Funktion zählt keine Referenzen, die in Closures versteckt sind. Zum Beispiel var a={n:1}; var b={a:function(){return a}}; roughSizeOfObject(b) – Hier b nimmt Bezug auf aaber roughSizeOfObject() kehrt zurück 0.
– Roman Pominow
10. Mai 2014 um 15:22 Uhr
Guy Bedford
Mit dem Heap-Profiler von Google Chrome können Sie die Verwendung des Objektspeichers überprüfen.
Sie müssen in der Lage sein, das Objekt in der Spur zu lokalisieren, was schwierig sein kann. Wenn Sie das Objekt an das globale Fenster anheften, ist es ziemlich einfach, es im Auflistungsmodus “Containment” zu finden.
Im beigefügten Screenshot habe ich ein Objekt namens “testObj” im Fenster erstellt. Ich habe es dann im Profiler (nachdem ich eine Aufnahme gemacht habe) gefunden und es zeigt die volle Größe des Objekts und alles darin unter “beibehaltene Größe”.
Im obigen Screenshot zeigt das Objekt eine beibehaltene Größe von 60. Ich glaube, die Einheit ist hier Bytes.
Diese Antwort löste mein Problem zusammen mit: developer.google.com/chrome-developer-tools/docs/… . Schneller Tipp: Machen Sie einen schnellen Heap-Snapshot, führen Sie die Aufgabe aus, von der Sie vermuten, dass sie leckt, machen Sie einen neuen schnellen Heap-Snapshot und wählen Sie die aus comparison Ansicht unten. Es macht deutlich, welche Objekte zwischen den beiden Schnappschüssen erstellt wurden.
– Johnride
28. März 2014 um 15:13 Uhr
Der von @Johnride erwähnte Vergleich ist jetzt oben ein Pulldown-Menü.
– frandroid
7. April 2016 um 18:42 Uhr
Shallow size scheint als 40 für beide { a:"55c2067aee27593c03b7acbe", b:"55c2067aee27593c03b7acbe", c:null, d:undefined } und { c:null, d:undefined } Objekte. Ist es o.k?
– efkan
4. April 2017 um 14:58 Uhr
Sie können den Google Chrome Heap Profiler auch vom Knoten aus verwenden. Wenn Sie Node v8 oder höher haben, starten Sie es mit node --inspect und in Chrome eingeben about:inspect in der URL-Leiste und suchen Sie nach dem Öffnen des Node-Inspektors. Erstellen Sie Ihr Objekt in der Knoten-CLI und erstellen Sie dann einen Heap-Snapshot.
– Gregor
18. September 2018 um 11:42 Uhr
Thomas Peter
Ich habe dies nur geschrieben, um ein ähnliches (ish) Problem zu lösen. Es macht nicht genau das, wonach Sie suchen, dh es berücksichtigt nicht, wie der Interpreter das Objekt speichert.
Aber wenn Sie V8 verwenden, sollte es Ihnen eine ziemlich gute Annäherung geben, da das fantastische Prototyping und die versteckten Klassen den größten Teil des Overheads auffressen.
function roughSizeOfObject( object ) {
var objectList = [];
var recurse = function( value )
{
var bytes = 0;
if ( typeof value === 'boolean' ) {
bytes = 4;
}
else if ( typeof value === 'string' ) {
bytes = value.length * 2;
}
else if ( typeof value === 'number' ) {
bytes = 8;
}
else if
(
typeof value === 'object'
&& objectList.indexOf( value ) === -1
)
{
objectList[ objectList.length ] = value;
for( i in value ) {
bytes+= 8; // an assumed existence overhead
bytes+= recurse( value[i] )
}
}
return bytes;
}
return recurse( object );
}
zEintopf
Manchmal verwende ich dies, um wirklich große Objekte zu kennzeichnen, die möglicherweise vom Server zum Client gehen. Es stellt nicht den Speicherbedarf dar. Sie erhalten nur ungefähr, was es kosten würde, es zu senden oder zu lagern.
Beachten Sie auch, dass es langsam ist, nur für Entwickler. Aber um eine Baseball-Antwort mit einer Codezeile zu bekommen, war es für mich nützlich.
roughObjSize = JSON.stringify(bigObject).length;
Dan
Hier ist eine etwas kompaktere Lösung des Problems:
Nettes Skript, benötigt jedoch Änderungen für zyklische Referenzen.
– Jim Pedid
8. Februar 2018 um 19:22 Uhr
Ich habe Ihren Algorithmus gerade an einer riesigen Datenmenge innerhalb eines Knotenprozesses getestet. Er meldet 13 GB, aber der Knoten verbraucht 22 GB. Haben Sie eine Ahnung, woher der Unterschied kommt? In Erinnerung ist nichts mehr.
– Josu Goñi
24. März 2018 um 22:03 Uhr
@JosuGoñi, sie berechnen nicht, wie viel das Objekt selbst braucht, sondern nur seinen Wert. Alle Objekte nehmen sonst mehr Platz ein als nur ihren Wert typeof ... würde nicht funktionieren.
var sizeof = require('object-sizeof');
// 2B per character, 6 chars total => 12B
console.log(sizeof({abc: 'def'}));
// 8B for Number => 8B
console.log(sizeof(12345));
var param = {
'a': 1,
'b': 2,
'c': {
'd': 4
}
};
// 4 one two-bytes char strings and 3 eighth-bytes numbers => 32B
console.log(sizeof(param));
Das ist also die Größe in KB? oder Bits?
– Vincent Thorpe
6. Dezember 2017 um 0:00 Uhr
@vincent-thorpe Es ist in Bytes.
– Dan
7. Dezember 2017 um 16:43 Uhr
Nettes Skript, benötigt jedoch Änderungen für zyklische Referenzen.
– Jim Pedid
8. Februar 2018 um 19:22 Uhr
Ich habe Ihren Algorithmus gerade an einer riesigen Datenmenge innerhalb eines Knotenprozesses getestet. Er meldet 13 GB, aber der Knoten verbraucht 22 GB. Haben Sie eine Ahnung, woher der Unterschied kommt? In Erinnerung ist nichts mehr.
– Josu Goñi
24. März 2018 um 22:03 Uhr
@JosuGoñi, sie berechnen nicht, wie viel das Objekt selbst braucht, sondern nur seinen Wert. Alle Objekte nehmen sonst mehr Platz ein als nur ihren Wert typeof ... würde nicht funktionieren.
– Alexis Wilke
27. Dezember 2018 um 10:19 Uhr
Gemeinschaft
Dies ist eine hackige Methode, aber ich habe es zweimal mit unterschiedlichen Zahlen versucht und es scheint konsistent zu sein.
Was Sie tun können, ist zu versuchen, a zuzuweisen enorm Anzahl von Objekten, wie ein oder zwei Millionen Objekte der gewünschten Art. Legen Sie die Objekte in einem Array ab, um zu verhindern, dass der Garbage Collector sie freigibt (beachten Sie, dass dies aufgrund des Arrays einen leichten Speicher-Overhead hinzufügt, aber ich hoffe, das sollte keine Rolle spielen, und außerdem, wenn Sie sich Sorgen machen, dass Objekte im Speicher sind , Sie speichern sie irgendwo). Fügen Sie vor und nach der Zuweisung eine Warnung hinzu und überprüfen Sie in jeder Warnung, wie viel Speicher der Firefox-Prozess beansprucht. Bevor Sie die Seite mit dem Test öffnen, vergewissern Sie sich, dass Sie eine neue Firefox-Instanz haben. Öffnen Sie die Seite und notieren Sie sich die Speicherauslastung, nachdem die „Vorher“-Warnung angezeigt wurde. Schließen Sie die Warnung und warten Sie, bis der Speicher zugewiesen wurde. Subtrahieren Sie den neuen Speicher vom älteren und dividieren Sie ihn durch die Menge der Zuordnungen. Beispiel:
function Marks()
{
this.maxMarks = 100;
}
function Student()
{
this.firstName = "firstName";
this.lastName = "lastName";
this.marks = new Marks();
}
var manyObjects = new Array();
alert('before');
for (var i=0; i<2000000; i++)
manyObjects[i] = new Student();
alert('after');
Ich habe dies in meinem Computer ausprobiert und der Prozess hatte 48352 KB Speicher, als die “Vorher” -Warnung angezeigt wurde. Nach der Zuweisung hatte Firefox 440236 KB Speicher. Bei 2 Millionen Zuordnungen sind dies etwa 200 Bytes für jedes Objekt.
Ich habe es noch einmal mit 1 Million Zuweisungen versucht und das Ergebnis war ähnlich: 196 Bytes pro Objekt (ich nehme an, die zusätzlichen Daten in 2 Millionen wurden für Array verwendet).
Also, hier ist eine Hacky-Methode, die Ihnen helfen könnte. JavaScript bietet aus einem bestimmten Grund keine “sizeof”-Methode: Jede JavaScript-Implementierung ist anders. In Google Chrome zum Beispiel verwendet dieselbe Seite ungefähr 66 Bytes für jedes Objekt (zumindest nach dem Task-Manager zu urteilen).
Hey.. danke für die Technik. Ich hatte das als Plan B, falls es keine direkte Möglichkeit gab, die Speichernutzung zu messen.
– anonym
8. August 2009 um 10:38 Uhr
Jede C- und C++-Implementierung ist auch anders. 😉 Die Größe eines Datentyps in C oder C++ ist implementierungsspezifisch. Ich sehe keinen Grund, warum JavaScript einen solchen Operator nicht unterstützen könnte, obwohl er nicht denselben Zweck erfüllen oder dieselbe Bedeutung haben würde wie in C oder C++ (die Sprachen niedrigerer Ebene sind und die tatsächliche Größe eines festen size-Datentyp zur Kompilierzeit im Gegensatz zur Variablengröße eines dynamischen JavaScript-Objekts zur Laufzeit).
– Bambus
21. Oktober 2009 um 17:48 Uhr
9165200cookie-checkWie erhalte ich die Größe eines JavaScript-Objekts?yes
Was ist mit der Antwort auf diese Frage: stackoverflow.com/questions/4391575/…
– cstrutz
5. September 2012 um 16:11 Uhr
Eine weitere Speichernäherungsfunktion auf Github.
– Rafael Emshoff
19. Mai 2015 um 16:07 Uhr