Warum nimmt Sytem.totalMemory ständig zu?

7

Ich habe dieses leere Projekt, nur um die Variable System.totalMemory auszuchecken. Soweit ich sehen kann, bekomme ich diese Werte:

%Vor%

Ich hatte kein Flash geöffnet, keinen Internet Browser, keine andere Flash-Instanz.

Das Projekt ist leer, nur ein statischer Text und ein dynamischer Text, der "Speicher" genannt wird. Eine *. Als Datei, die diesen Code enthält:

%Vor%

Dies sind meine Veröffentlichungseinstellungen.

Ich habe im Debug und Published * .swf die gleichen Ergebnisse getestet.

Ich habe keine Ahnung von diesem, also bitte helfen.

    
Veehmot 19.06.2009, 21:39
quelle

5 Antworten

25

Ich denke, Sie haben ein paar Dinge falsch.

Zuerst zeigen Ihre Traces totalMemory die letzten drei Ziffern an (da Sie es nicht im Code tun, nehme ich an, dass es an der TextField-Breite liegt). Es wächst wie folgt: 3076, 3092, 3096 usw. Dies sind (grob) Kilobyte, keine Bytes. Dann kommentieren Sie: "totalMemory nach 2 Stunden: 3887104. Mein Gott". Wenn Sie nun mit 3.887.104 3.887.104 Kb meinen, wären das etwa 3,8 Gb. Ich bezweifle, dass das der Fall ist. Nehmen wir an, Sie meinen 3.887.104 Bytes. Das sind ungefähr 3.800 Kb oder 3.8 Mb. Nicht so viel Speicher, tatsächlich, und noch wichtiger, nicht so weit von Ihren ursprünglichen 3.076 Kb.

Ich denke, dass dies tatsächlich ein anderes Poster in die Irre führt, dass der Player die Speicherbelegung um 4 Bytes erhöht hat, wenn er tatsächlich um 4.096 Bytes oder 4 KB erhöht wird.

Zweitens, obwohl der Code sehr einfach ist, verbraucht er Speicher. Zunächst wird jedes Mal, wenn das Ereignis ENTER_FRAME ausgelöst wird, ein Event-Objekt erstellt, das wiederum Verweise auf andere Objekte, Strings usw. enthält. Das braucht Erinnerung. Dann konvertieren Sie eine Zahl implizit in eine Zeichenkette (indem Sie totalMemory drucken). Das erfordert auch Speicher, ob Sie eine explizite Konvertierung durchführen oder nicht (das gleiche gilt, wenn Sie eine Ablaufverfolgung erstellen, anstatt ein Textfeld zu verwenden). Darüber hinaus gibt es sicher noch andere Sachen, die aus einer "ActionScript-Sicht" nicht ersichtlich sind.

Nun, ich denke, ein Teil des Problems besteht darin, dass Sie nur den aktuellen totalMemory verfolgen. Wenn man es betrachtet, scheint es, als würde es langsam, aber stetig wachsen. Und das ist wahr, aber Sie werden wahrscheinlich vermissen, dass der GC mit einer langsameren Geschwindigkeit loslegt und viel von dem Speicher freigibt, der sich angesammelt hat.

Dies wird deutlicher, wenn Sie den Code ändern, um einige Dinge zu berechnen.

%Vor%

Ich benutze Stücke von 4096 Bytes als die Einheit (Deshalb mache ich System.totalMemory & gt; & gt; 12. Nur eine schicke Art, System.totalMemory / 4096 zu sagen). Ich denke, es ist überschaubarer und sowieso totalMemory immer ein Vielfaches von 4096 byes oder 4kb. Sie können mehr über den GC von Flash hier lesen: Ссылка . Dieser Teil des Players ist Open Source, und Sie können die Quellen sogar lesen, wenn Sie dazu geneigt sind.

Eine kurze Erklärung, was der Code verfolgt:

  • time running: Sekunden, die vergangen sind, seit das SWF gestartet wurde
  • current: Die von System.totalMemory zurückgegebene Speichermenge in Blöcken von 4 KB
  • previous: Der vorherige Wert von totalMemory
  • diff: Der Unterschied zwischen dem aktuellen und dem vorherigen. Könnte negativ sein. Dies zeigt Ihnen, ob die Speicherbelegung gegenüber dem vorherigen Wert erhöht oder verringert wurde.
  • peak: Selbsterklärend. Das ist nicht sehr wichtig.
  • anzahl erhöhen: Die Häufigkeit, mit der der aktuelle Wert größer als der vorherige Wert war. Im Grunde sagt es Ihnen, wie oft der TotalMemory erhöht wurde, mindestens 1 Chunk.
  • sinkeCount: Die Häufigkeit, mit der der vorherige Wert größer als der aktuelle Wert war. Dadurch erfahren Sie, wie oft der Speicher freigegeben wurde.
  • accumIncrease: Der akkumulierte Wert von positiven Diffs. Gibt an, wie viele Chunks zugewiesen wurden.
  • accadDecrease: Der akkumulierte Wert von negativen Diffs. Ich werde Sie wissen lassen, wie viele Brocken veröffentlicht wurden.
  • maxIncrease: Die maximale Anzahl an Blöcken, die innerhalb von zwei Schleifenausführungen zugewiesen wurden.
  • maxDecrease: Die maximale Anzahl von Blöcken, die innerhalb von zwei Schleifenausführungen freigegeben werden.

Sehen wir uns nun einige "Schnappschüsse" an, die mit diesem Code erstellt wurden.

Dies ist ein früher Schnappschuss, der gemacht wurde, als der swf für 3 Sekunden lief. Beachten Sie, dass der aktuelle Wert 760 lautet.

  • Zeit läuft: 3 Sekunden
  • aktuell: 760
  • vorherige: 759
  • diff: 1
  • Spitze: 760
  • Erhöhungszahl: 3
  • Abnahmezahl: 0
  • accumIncrease: 6
  • accumDecrease: 0
  • maxIncrease: 3
  • maxDecrease: 0

Nach ungefähr 10 Minuten:

  • Zeit läuft: 574 Sekunden
  • aktuell: 763
  • vorherige: 762
  • curDiff: 1
  • Spitze: 834
  • Erhöhungszahl: 127
  • Abnahmezahl: 3
  • accumIncrease: 132
  • accumDecrease: 123
  • maxIncrease: 3
  • maxDecrease: 72

Ein paar Dinge zu beachten:

  1. Nach etwa 10 Minuten ist Strom sehr nah an dem, was es in 3 Sekunden war: 763 vs 760. Das bedeutet gerade jetzt, der Gesamtspeicher beträgt 3,052 Mb; Um 3 Sekunde, es war 3.040 Mb.
  2. Die Anzahl der Erhöhungen ist hoch und die Verringerung der Anzahl ist gering. Das bedeutet Der Spieler hat Speicher a zugewiesen viele Male aber veröffentlicht es sehr sparsam.
  3. maxIncrease ist niedrig und maxDecrease ist hoch. Fügen Sie das zu 2) hinzu und Sie haben ein interessantes Muster: Der Spieler weist eine kleine Anzahl von Blöcken zu häufig. Es gibt sie bei a viel langsamer; wenn es doch so ist gibt eine große Anzahl von Stücken frei.
  4. accumIncrease und accadDecrease sind sehr nah auch.

Nun, lass die swf noch etwas laufen. Nach einer Laufzeit von 50 Minuten sieht der Schnappschuss so aus:

  • Zeit läuft: 2989 Sekunden
  • aktuell: 931
  • vorherige: 930
  • diff: 1
  • Spitze: 931
  • Erhöhungszahl: 690
  • Abnahmezahl: 8
  • accumIncrease: 699
  • accumDecrease: 522
  • maxIncrease: 3
  • maxDecrease: 163

An dieser Stelle könnten Sie denken, dass es ein Leck gibt. Beachten Sie, dass der aktuelle Speicher 931 im Vergleich zu den ursprünglichen 760 ist.

Aber schauen Sie, was bei 3124 Sek. passiert, ~ 52 Minuten:

  • Zeit läuft: 3142 sec
  • aktuell: 767
  • vorherige: 768
  • diff: -1
  • Spitze: 962
  • ZunahmeZahl: 720
  • Abnahmezahl: 10
  • accumIncrease: 730
  • accadDecrease: 717
  • maxIncrease: 3
  • maxDecrease: 194

Bevor der GC eintrat, stieg der Höchststand auf 962. Aber danach ging die Stromstärke auf 767 zurück, wiederum sehr nahe bei den anfänglichen 760.

Also, um es auf den neuesten Stand zu bringen, bedeutet die Tatsache, dass die Speichernutzung zunimmt, nicht unbedingt, dass es ein Leck gibt. Sie müssen nur mit der Tatsache umgehen, dass der Spieler Müll gesammelt wird, und dieser Prozess ist nicht deterministisch. Der Speicher wird irgendwann zurückgewonnen (es sei denn, Sie haben natürlich ein Leck in Ihrem Code). Sie können nicht bestimmen, wann dies passieren wird. Es wird passieren, wenn der Spieler bestimmt, dass es notwendig ist. Und im Allgemeinen weiß der Spieler es besser.

Das heißt, ich denke, es ist wichtig, auf mögliche Lecks in Ihrem Code zu achten. Aber das Verfolgen von System.totalMemory wird Ihnen nicht dabei helfen, das zu bestimmen. Verwenden Sie, wenn möglich, ein Tool wie den Speicherprofiler von Flex Builder, der zwar nicht perfekt ist, Ihnen aber viel mehr nützliche Informationen bietet. Seien Sie vorsichtig beim Hinzufügen von Zuhörern zur Bühne, und wenn Sie Timer verwenden, werden die größten Fehler im Flash Player verursacht.

    
Juan Pablo Califano 20.06.2009, 21:53
quelle
1

Sie können überprüfen, welche Version des Flash-Players Sie gerade ausführen. Wenn Sie die IDE installiert haben, gibt es eine gute Chance, dass Sie in der Debug-Version des Players laufen - was dazu führt, dass der Speicher im Vergleich zum normalen Player fast nicht mehr so ​​oft freigegeben wird.

Wenn Sie im Debug-Player laufen, können Sie einen GC-Sweep erzwingen - System.gc ();

    
Branden Hall 20.06.2009 04:53
quelle
0

Soweit ich feststellen kann, gibt der Aufruf von System.totalMemory in jeder Schleife einen Wert zurück, der die Größe des von Flash verwendeten Speichers in Bytes angibt. Die durch den Aufruf von System.totalMemory zurückgegebene Benutzerkennung wird im Arbeitsspeicher gespeichert (d. H. Ihr RAM, nicht das Textfeld, das Sie als "Arbeitsspeicher" bezeichnet haben). Die memory.text-Referenz wird dann aktualisiert, um auf den Speicherplatz im Speicher zu zeigen, der von der Uint belegt ist. Die alte Uint ist noch in Erinnerung, aber es gibt keinen Hinweis darauf. Die Anzahl der Daten beträgt 32 Bit (4 Byte). Sie sehen also, dass Ihr Speicherbedarf jedes Mal um 4 Byte zunimmt. Sobald der Garbage Collector ausgeführt wird, sollte der Speicherplatz im Speicher, der von den jetzt freigegebenen Ständen belegt ist, freigegeben werden und Sie sollten den Speicherverlust sehen.

Wenn ich jedoch Ihren Beispielcode ausführe, bekomme ich nichts dergleichen. Es geht rauf und runter, es geht nicht beständig wie deines, aber ich bin auf OS X, also ist es ein anderer Player.

    
jorelli 19.06.2009 22:52
quelle
0

Da sich der Text im Textfeld ändert, muss Flash verschiedene Zeichen in den Speicher laden, um sie anzuzeigen. Dies könnte die paar hundert Bytes an Steigerung erklären, die Sie bekommen.

Bleibt allein, um wie viel größer ist der Fußabdruck?

UPDATE: Nachdem ich darüber nachgedacht habe, denke ich, dass es mit den temporären Bitmap-Grafiken zu tun hat, die für Flash zum Rendern von Text erstellt werden ... obwohl man das mit trace nicht erwartet ... obwohl trace einiges tun muss interne Dinge auch ...

Haben Sie daran gedacht, es in FlexBuilder auszuführen? Das hat ein Profiling-Tool, das Ihnen sagen kann, wohin Ihr Gedächtnis geht.

    
Iain 19.06.2009 21:57
quelle
0

Vielleicht ist das offensichtlich, aber denken Sie daran, dass System.totalMemory Ihnen die Speicherkapazität gibt, die von Flash Player verwendet wird (statisch). Wenn Sie eine andere Flash-Anwendung geöffnet haben, könnte dies erklären, warum Ihr Speicher zunimmt.

    
gabriel-laet 22.06.2009 12:12
quelle