Membongkar ByteArray menggunakan Actionscript 3

91

Bagaimana cara membongkar secara paksa ByteArraydari memori menggunakan ActionScript 3?

Saya telah mencoba yang berikut ini:

// First non-working solution
byteArray.length = 0;
byteArray = new ByteArray();

// Second non-working solution
for ( var i:int=0; i < byteArray.length; i++ ) {
    byteArray[i] = null;
}
Rann Lifshitz
sumber

Jawaban:

35

Saya tidak berpikir Anda perlu khawatir. Jika System.totalMemoryturun Anda bisa santai. Mungkin saja OS tersebut tidak mendapatkan kembali memori yang baru dibebaskan (untuk mengantisipasi saat Flash Player akan meminta lebih banyak memori).

Coba lakukan sesuatu yang sangat intensif memori dan saya yakin Anda akan melihat bahwa memori yang dialokasikan ke Flash Player akan berkurang dan sebagai gantinya digunakan untuk proses lain.

Seperti yang saya pahami, manajemen memori di OS modern tidak intuitif dari perspektif melihat jumlah yang dialokasikan untuk setiap proses, atau bahkan jumlah total yang dialokasikan.

Saat saya menggunakan Mac selama 5 menit, 95% dari RAM 3 GB saya digunakan, dan akan tetap seperti itu, tidak pernah mati. Itulah cara OS menangani memori.

Selama tidak diperlukan di tempat lain, bahkan proses yang telah berhenti masih memiliki memori yang ditetapkan padanya (ini dapat membuatnya diluncurkan lebih cepat di lain waktu, misalnya).

Theo
sumber
25

(Saya tidak yakin tentang ini, tapi ...)

AS3 menggunakan pengumpulan sampah non-deterministik yang berarti bahwa memori yang didereferensi akan dibebaskan setiap kali runtime terasa seperti itu (biasanya tidak kecuali jika ada alasan untuk dijalankan, karena ini adalah operasi yang mahal untuk dijalankan). Ini adalah pendekatan yang sama yang digunakan oleh sebagian besar bahasa pengumpulan sampah modern (seperti C # dan Java juga).

Dengan asumsi tidak ada referensi lain ke memori yang ditunjuk oleh byteArrayatau item di dalam larik itu sendiri, memori akan dibebaskan di beberapa titik setelah Anda keluar dari ruang lingkup di mana byteArraydideklarasikan.

Anda dapat memaksa pengumpulan sampah, meskipun sebenarnya tidak seharusnya. Jika Anda melakukannya, lakukan hanya untuk pengujian. Jika Anda melakukannya dalam produksi, Anda akan merusak kinerja lebih dari sekadar membantunya.

Untuk memaksa GC, coba (ya, dua kali):

flash.system.System.gc();
flash.system.System.gc();

Anda dapat membaca lebih lanjut di sini .

Karl Seguin
sumber
20

Lihat artikel ini

http://www.gskinner.com/blog/archives/2006/06/as3_resource_ma.html

Programmer skrip tindakan IANA, bagaimanapun perasaan yang saya dapatkan adalah, karena pengumpul sampah mungkin tidak berjalan ketika Anda menginginkannya.

Karenanya http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/

Jadi saya akan merekomendasikan mencoba kode koleksi mereka dan melihat apakah itu membantu

private var gcCount:int;
private function startGCCycle():void{
    gcCount = 0;
    addEventListener(Event.ENTER_FRAME, doGC);
}
private function doGC(evt:Event):void{
    flash.system.System.gc();
    if(++gcCount > 1){
        removeEventListener(Event.ENTER_FRAME, doGC);
        setTimeout(lastGC, 40);
    }
}
private function lastGC():void{
    flash.system.System.gc();
}
Jax
sumber
16

Sayangnya ketika datang ke manajemen memori di Flash / skrip tindakan tidak banyak yang dapat Anda lakukan. ActionScript dirancang agar mudah digunakan (jadi mereka tidak ingin orang-orang khawatir tentang manajemen memori)

Berikut ini adalah solusinya, daripada membuat ByteArrayvariabel coba ini.

var byteObject:Object = new Object();

byteObject.byteArray = new ByteArray();

...

//Then when you are finished delete the variable from byteObject
delete byteObject.byteArray;

Di mana byteArrayproperti dinamis dari byteObject, Anda dapat membebaskan memori yang dialokasikan untuknya.

Redbaron
sumber
16

Saya yakin Anda telah menjawab pertanyaan Anda sendiri.

System.totalMemorymemberi Anda jumlah total memori yang "digunakan", tidak dialokasikan. Memang akurat bahwa aplikasi Anda mungkin hanya menggunakan 20 MB, tetapi memiliki 5 MB yang gratis untuk alokasi di masa mendatang.

Saya tidak yakin apakah dokumen Adobe akan menjelaskan cara mengelola memori.

Redbaron
sumber
11

Jadi, jika saya memuat katakanlah 20MB dari MySQL, di Task Manager, RAM untuk aplikasi naik sekitar 25MB. Kemudian ketika saya menutup koneksi dan mencoba membuang ByteArray, RAM tidak pernah lepas. Namun, jika saya menggunakan System.totalMemory, flash player menunjukkan bahwa memori sedang dilepaskan, padahal sebenarnya tidak demikian.

Apakah flash player melakukan sesuatu seperti Java dan memesan ruang heap dan tidak melepaskannya hingga aplikasi ditutup?

Ya dan tidak, karena Anda mungkin telah membaca dari posting blog yang tak terhitung jumlahnya bahwa GC di AVM2 optimis dan akan bekerja dengan caranya sendiri yang misterius. Jadi ini berfungsi seperti Java dan mencoba memesan ruang heap. Namun jika Anda membiarkannya cukup lama dan mulai melakukan operasi lain yang memakan beberapa memori signifikan, ruang sebelumnya akan kosong. Anda dapat melihatnya menggunakan profiler dalam semalam dengan beberapa pengujian yang dijalankan di atas aplikasi Anda.

Pedro
sumber
10

Jadi, jika saya memuat katakanlah 20MB dari MySQL, di Task Manager, RAM untuk aplikasi naik sekitar 25MB. Kemudian ketika saya menutup koneksi dan mencoba membuang ByteArray, RAM tidak pernah lepas. Namun, jika saya menggunakan System.totalMemory, flash player menunjukkan bahwa memori sedang dilepaskan, padahal sebenarnya tidak demikian.

Pemain "melepaskan" memori. Jika Anda meminimalkan jendela dan memulihkannya, Anda akan melihat bahwa memeory sekarang lebih mirip dengan apa yang ditampilkan System.totalMemory.

Anda mungkin juga tertarik untuk menggunakan alat pembuatan profil FlexBuilder yang dapat menunjukkan kepada Anda apakah Anda benar-benar mengalami kebocoran memori.


sumber