Вивантаження масиву ByteArray за допомогою Actioncript 3


91

Як примусово вивантажити a ByteArrayз пам'яті за допомогою ActionScript 3?

Я спробував наступне:

// 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;
}

Відповіді:


35

Думаю, вам нема про що турбуватися. Якщо System.totalMemoryзійде, ви можете розслабитися. Цілком може бути, що ОС не повертає щойно звільнену пам’ять (очікуючи наступного разу, коли Flash Player попросить більше пам’яті).

Спробуйте зробити щось інше, що вимагає великої пам’яті, і я впевнений, що ви помітите, що пам’ять, виділена Flash Player, зменшиться і замість цього буде використана для іншого процесу.

Як я зрозумів, управління пам’яттю в сучасних ОС не є інтуїтивним з точки зору розгляду суми, виділеної для кожного процесу, або навіть загальної суми, що виділяється.

Коли я використовую свій Mac протягом 5 хвилин, використовується 95% моєї оперативної пам'яті обсягом 3 Гб, і вона залишиться такою, вона ніколи не знизиться. Саме так ОС обробляє пам’ять.

Поки це не потрібно в інших місцях, навіть у процесів, які завершили роботу, пам'ять їм призначена (наприклад, це може зробити їх швидшим запуском наступного разу).


25

(Я не впевнений у цьому, але ...)

AS3 використовує недетермінований збір сміття, що означає, що дереференційна пам'ять звільнятиметься кожного разу, коли схоже на час виконання (як правило, за винятком випадків, коли є причина для запуску, оскільки це дорога операція для виконання). Це той самий підхід, який використовують більшість сучасних мов для збору сміття (таких як C # та Java також).

Припускаючи, що немає інших посилань на пам’ять, на яку вказує, byteArrayабо елементи в самому масиві, пам’ять звільниться в якийсь момент після того, як ви вийдете з області, де byteArrayоголошено.

Ви можете змусити збирати сміття, хоча насправді не повинні. Якщо так, зробіть це лише для тестування. Якщо ви робите це на виробництві, ви набагато більше пошкодите продуктивності, ніж допоможете.

Щоб примусити GC, спробуйте (так, двічі):

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

Детальніше ви можете прочитати тут .


20

Погляньте на цю статтю

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

Програміст IANA actionscript, однак відчуття у мене таке, бо збирач сміття може не працювати, коли ви цього захочете.

Звідси http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/

Тому я рекомендую спробувати їх колекційний код і подивитися, чи допомагає він

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();
}

16

На жаль, що стосується управління пам’яттю у Flash / actionscript , ви не можете багато чого зробити. ActionScript був розроблений таким, щоб бути простим у використанні (тому вони не хотіли, щоб люди турбувалися про управління пам’яттю)

Далі наведено обхідний шлях, замість створення ByteArrayзмінної спробуйте це.

var byteObject:Object = new Object();

byteObject.byteArray = new ByteArray();

...

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

Де byteArrayзнаходиться динамічна властивість byteObject, ви можете звільнити пам’ять, яка була виділена для нього.


16

Я вважаю, що ви відповіли на власне запитання.

System.totalMemoryнадає загальний обсяг пам'яті, яка "використовується", а не виділяється. Точно, що ваша програма може використовувати лише 20 МБ, але вона має 5 МБ, які є безкоштовними для подальшого розподілу.

Я не впевнений, чи просвітять документи Adobe про спосіб управління пам’яттю.


11

Отже, якщо я завантажую, скажімо, 20 МБ з MySQL, у диспетчері завдань оперативна пам’ять для програми збільшується приблизно на 25 МБ. Потім, коли я замикаю з'єднання і намагаюся розпоряджатися ByteArray, оперативна пам'ять ніколи не звільняється. Однак, якщо я використовую System.totalMemory, флеш-плеєр показує, що пам'ять звільняється, що не так.

Чи виконує флеш-плеєр щось на зразок Java і резервує простір купи і не випускає його до виходу програми?

Ну так і ні, як ви, можливо, читали з незліченних постів у блозі, що GC в AVM2 оптимістичний і буде працювати своїми таємничими способами. Тому він працює трохи як Java і намагається зарезервувати кучу простору. Однак якщо ви дозволите йому досить довго і почнете робити інші операції, які забирають значну пам’ять, це звільнить попередній простір. Ви можете переконатися в цьому, використовуючи профайлер протягом ночі, а деякі тести запущені поверх вашої програми.


10

Отже, якщо я завантажую, скажімо, 20 МБ з MySQL, у диспетчері завдань оперативна пам’ять для програми збільшується приблизно на 25 МБ. Потім, коли я замикаю з'єднання і намагаюся розпоряджатися ByteArray, оперативна пам'ять ніколи не звільняється. Однак, якщо я використовую System.totalMemory, флеш-плеєр показує, що пам'ять звільняється, що не так.

Програвач "звільняє" пам'ять. Якщо згорнути вікно та відновити його, ви побачите, що меморіал набагато ближчий до того, що показує System.totalMemory.

Можливо, вас також зацікавить використання інструментів профілювання FlexBuilder, які можуть показати вам, чи справді у вас є витоки пам'яті.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.