آزاد سازی حافظه

BehrouzPc

پــــادشــاه فــلــــش
optimaize_flash_iflashlord.jpg




بهینه سازی در فلش یک اصل مهم به حساب می آید و افزایش و کار بر روی آن برای توسعه دهندگان فلش امری الزامی است. به عنوان یک توسعه دهنده فلش و به عنوان کسی که برای آینده این نرم افزار بزرگ احساس مسئولیت می کند ، ما وظیفه داریم در ساخت عناصر فلش که کارایی بهتری دارند پیش گام باشیم و همواره بهترین و بهینه ترین روش را استفاده کنیم. در این مجموعه آموزشی بهینه سازی فلش به نکات مهم برای مدیریت بر عناصر و حافظه ها … می پردازیم و تلاش می کنیم که بتوانیم با استفاده از نکات ارائه شده خروجی بهینه تر و سبک تری از پروژه فلش خود داشته باشیم.

آزاد سازی حافظه (Memory)

شما نمی توانید جمع آور زباله (garbage collector) را به صورت مستقیم در فلش پلیر اجرا کنید. برای این که اطمینان پیدا کنید که یک شی جمع آوری شده است می بایست تمامی منابع آن را حذف کنید. به یاد داشته باشید که عملگر مورد استفاده در اکشن اسکریپت ۱ و ۲ رفتار متفاوتی در اکشن اسکریپت ۳ دارد. این مورد را تنها می توان برای حذف خصوصیات پویا (Dynamic) از یک شی پویا استفاده نمود.
توضیح : جمع آوری زباله (Garbage collection) یک اصطلاح می باشد که به عمل پاک سازی و جمع آوری اشیاء (object) هایی که استفاده ای نمی شوند و حافظه را اشغال کرده اند ، اطلاق می شود.

تذکر: شما می توانید جمع آوری کننده زباله (garbage collector) را در ادوبی ایر (Adobe AIR) و نسخه (Debug) فلش پلیر به صورت مستقیم فراخوانی کنید.
به عنوان مثلا ،در کد زیر منابع یک Sprite را برابر با null قرار می دهیم ؛ و با این کار جمع آور زباله آن را از حافظه حذف می کند.


PHP:
var mySprite:Sprite = new Sprite();
 
// منابع مربوطه با نال (تهی) مقدار دهی شد و در نتیجه جمع آور زباله این مورد را از حافظه حدف می کند.
mySprite = null;
به یاد داشته باشید زمانی که به یک شی مقدار null را می دهید ، لزوما از حافظه حذف نخواهد شد. بعضی اوقات اگر حافظه موجود کمتر از مقدار کافی به نظر نرسد جمع آور زباله (garbage collector) اجرا نمی شود. جمع آوری زباله (Garbage collection) قابل پیشبینی نیست.
تخصیص درست حافظه ، ترجیح داده می شود به حذف شی (obejct) و آغاز جمع آوری زباله.
زمانی که جمع آورنده زباله (garbage collector) اجرا می شود ،فهرستی از اشیاء ی که جمع آوری نشده است را ایجاد می کند. حال اشیاء غیر فعال درون فهرست که دیگر استفاده نمی شوند ، با تشخیص منابع اشیاء در دیگر اشیاء ، مشخص می شود ، اشیاء غیرفعالشناسایی شده از این راه حذف می شوند.
در برنامه های بزرگ ، این فرایند می تواند باعث تشدید فشار بر پردازنده (CPU-intensive) ، تاثیر بر کارایی برنامه (performance) و کاهش قابل توجه سرعت در برنامه شود. سعی کنید به منظور محدود کردن جمع آوری زباله (garbage collection) تا آن جا که امکان پذیر است از ، استفاده دوباره از اشیاء استفاده کنید.
همچنین از دادن مقدار null به منابع بی استفاده ، در زمانی که امکان دارد ، استفاده کنید. با این کار جمع آورنده زباله (garbage collector) پردازش کمتری برای پیدا کردن اشیاء خواهد داشت. می توان به جمع آوری زباله (garbage collection) مثل بیمه حافظه مصرفی یک برنامه نگاه کرد ، و در ضمن همیشه سعی کنید به مدیریت طول عمر اشیاء (در صورت امکان) دقت کنید.
تذکر : تعیین یک مرجع از یک شی نمایشی (display object) با مقدار null تضمینی برای این که آن شی منجمد (freeze) شده باشد نیست. شی همچنان به مصرف پردازنده (CPU) در سیکل زمانی ادامه می دهد تا زمانی که جمع آوری زباله انجام شود. قبل از مقدار دهی منابع به null ، اطمینان حاصل کنید که شی شما به درسی غیر فعال شده است.
جمع آورنده زباله را می توانید با استفاده از متد System.gc() فراخوانی کنید ، البته توجه داشته باشید این فراخوانی مستقیم مربوطه به Adobe Air و فلش پلیر نسخه Debug می باشد. Profiler toolbar ی که همراه برنامه Adobe Flash Builder می باشد به شما این امکان را می دهد که به صورت دستی جمع آور زباله (garbage collector) را شروع کنید. با اجرای جمع آورنده زباله شما این امکان را دارید که مشاهده کنید که چگونه برنامه شما پاسخ می دهد و آیا اشیاء به درستی از حافظه حذف شده است یا خیر.
تذکر : اگر یک شی به عنوان یک شنونده (listener) رویداد استفاده شده است ، شی دیگر می تواند به آن ارجاع شود. اگر این حالت باشد ، می بایست رویداد شنوندها توسط متد removeEventListener() قبل از مقدار دهی null به شی حذف شود.
خوشبختانه ، مقدار حافظه استفاده شده توسط bitmap ها را می توان مستقیم کاهش داد. به عنوان مثل کلاس BitmapData دارای متد dispose() می باشد. در مثال بعدی ، یک BitmapData ایجاد می کنیم (۱.۸MB حافظه). حافظه جاری به مقدار ۱.۸MB افزایش پیدا می کند. توسط خصوصیت System.totalMemory می توانیم خروجی حافظه اشغال شده را مشاهده کنیم :


PHP:
trace(System.totalMemory / 1024);
// خروجی : ۴۳۱۰۰
 
//  ساخت یک نمونه BitmapData
var image:BitmapData = new BitmapData(800, 600);
 
trace(System.totalMemory / 1024);
// خروجی : ۴۴۹۶۴
در مثال بعدی BitmapData ساخته شده به صورت دستی از حافظه حذف می شود (با کمک متد dispose) و دوباره مقدار حافظه چک می شود :
PHP:
trace(System.totalMemory / 1024);
// خروجی: ۴۳۱۰۰
//  ساخت یک نمونه BitmapData
var image:BitmapData = new BitmapData(800, 600);
 
trace(System.totalMemory / 1024);
// خروجی : ۴۴۹۶۴
 
image.dispose();
image = null;
 
trace(System.totalMemory / 1024);
// خروجی : ۴۳۰۸۴
اگر چه متد dispose() پیکسل ها را از حافظه حذف می کند ، می بایست هنوز به مرجع مقدار null (تهی) داده شود تا رها سازی به صورت کامل انجام شود. همیشه سعی کنید زمانی که نیازی به شی BitmapData ندارید از متد dispose() استفاده کنید و به مرجع نیز مقدار تهی (null) اختصاص دهید ، با این کار حافظه بلافاصله آزاد می شود.
تذکر : فلش پلیر ۱۰.۱ و ادوبی ایر ۱.۳.۲ متد جدیدی با نام disposeXML() بر روی کلاس های System معرفی نموده اند. این متد به شما این امکان را می دهد که با مقدار دهی XML tree به عنوان پارامتر آن ، شی XML را بلافاصله برای جمع آوری زباله (garbage collection) آماده کنید.

موفق و پیروز باشید.


منبع
 
آخرین ویرایش:

++Hadi++

Active Member
خیلی ممنون مرد بزرگ
در ضمن قابل ذکر هست که وقتی یه swf رو در فلش و اکشت اسکریپت 3 لود می کنیم ، می تونیم در مواقعی که نیاز به اون نداریم ، اونو unloadAndStop کنیم که البته یکی از پارامتر ایی که این متد می گیره ، یه بولین برای gc یا همون garbage collection رو می گیره که اگه به صورت پیش فرض true باشه ، تمام امعا و احشای اون مووی کلیپ رو پاک می کنه و بهتره قبلش تمامی event های داخل اون swf لود شده رو remove کنیم و بعد این کار رو انجام بدیم . یکی از مزایای این دستور در کلاس loader اینه که صدای در حال جریان swf لود شده رو هم قطع می کنه .
PHP:
var loader:Loader=new Loader();
var loadedBol:Boolean=false;
addChild(loader);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,comp);
loader.contentLoaderInfo.addEventListener(IOErrprEvent.IO_ERROR,err);
loader.load(new URLREquest("mySWF.swf"));
unloadBTN.addEventListener(MouseEvent.CLICK,clicki);

function comp(evt:Event):void
{
   trace("complete!");
   loadedBol=true;
}
function err(evt:IOErrorEvent):void
{
    trace("Error");
}
function clicki(evt:MouseEvent):void
{
   loader.unloadAndStop(true/*default pos*/);
}
موفق باشید ...
 

amird

خبرگان انجمن فلش
سلام و خسته نباشید خدمت بهروز یار نمایشگاهی :)
راستش من یه پروژه دارم که فکر کنم دقیقا مشکل حافظه ای داره و راستش هر چی هم باهاش کلنجار رفتم نتوسنتم کاریش کنم .اومدم تاپیک بزنم که دیدم همچین تاپیکی رو نوشتی فکر کنم مطرح کردن سوالم هم اینجا بشه یک مثال برای آموزش خوبت.
اقا ببین من فریم های پروژم زیاد هست حدود 5000 تا (البته پروژه از کلی فایل Swf تشکیل شده که هر فایل swf اینقدر هست) بعدش توی هر فایل چندتا دکمه هست برای رفتن به مرحله قبل و بعد هر فایل هم حدود از 3 4 تا مرحله داره تا 7 8 تا مرحله توی فایل هایی که مرحلشون کمه مشکلی وجود نداره اما فایل هایی که 7 8 تا مرحله دارن در اول که اجرا می شن خوب هستن اما بعد از یه مدتی که باهاشون کار می کنم و عقب و جلو می کنم آروم آروم سرعت کم می شه و دیگه به جایی می رسه که دیگه برنامه کلی معطل می کنه و به مرز هنگ شدن می رسه. دستوراتی که روی دکمه ها هست gotoandstop ساده هست (البته با یه خورده قر و فر ولی مشکل روی همین اصل مطلب gotoAndStop هست) ولی فکر کنم بخاطر همین که حافظه رو آزاد نمی کنم و فایل ها سنگین هستند اینطوری می شه.
حالا می خواستم ببینم من چطور می تونم این آزاد سازی رو انجام بدم؟
ممنون
 

BehrouzPc

پــــادشــاه فــلــــش
برای مورد شما این موارد کارایی دارد :

1- تا جایی که امکان دارد از تصاویر (Bitmap) به جای اشکال وکتور استفاده کنید.
2 - در صورت امکان از کلاس Bitmap استفاده کنید
3 - مختصات z مربوطه به MovieClip های خود را روی 0 قرار دهید (مهم در اینجا مقدار دهی است و نه مقدار 0 ) با این کار این شی به صورت یک Bitmap می شود
4 - برای unload حتما از unloadAndStop استفاده کنید
5 - تا جایی که امکان دارد از اشیاء موجود در پروژه دوباره و چند باره استفاده کنید (به جای ساخت مورد جدید برای هر مرحله)
6 - به حذف رویداد ها و به خصوص timer ها و interval ها و enterframe ها در زمانی که دیگر نیازی به آنها نیست توجه کنید
7 - برای اشکالی که متحرک نیستند از graphic و برای موارد متحرک از movieClip استفاده کنید
8 - حدالمقدور برای انمیمشن های طولانی و حرکت های که در زمان بیشن از 5 ثانیه است از افکت Blur استفاده نکنید

این موارد نکات مهمی بود که الان به ذهن بنده رسید...

البته توجه داشته باشید ، کاهش سرعت در این نوع پروژه ها بیشتر مربوطه به استفاده از طرح های وکتوری زیاد و انیمیشن ها و... می باشد.
 

amird

خبرگان انجمن فلش
ممنون بهروز جان من همه این چیزایی رو که گفتی یا رعایت کردم یا اصلا توی پروژه ام نیازی به استفاده ازشون نبوده.
ببین شاید مشکل من به این برگرده که من مجبورم توی فایل های swfم یک فیلم رو embed کنم و شاید بخاطر این هست که اینطوری می شه البته شاید هم نه ! واقعا گیجم کرده !!!
ببین نه انیمیشنی در کاره در چیز متحرک خاصی فقط همین فیلم هست و یک سری دکمه برای کنترل و یک چندتا عکس و این چیزا هم برای گرافیک . ولی حالا اینکه چرا اینها درست کار نمی کنن واقعا برام سوال هست.
اگر پیشنهاد دیگه ای هست گوش می کنم . واقعا کارم گیر کرده ...
بازم ممنون
 

BehrouzPc

پــــادشــاه فــلــــش
ممنون بهروز جان من همه این چیزایی رو که گفتی یا رعایت کردم یا اصلا توی پروژه ام نیازی به استفاده ازشون نبوده.
ببین شاید مشکل من به این برگرده که من مجبورم توی فایل های swfم یک فیلم رو embed کنم و شاید بخاطر این هست که اینطوری می شه البته شاید هم نه ! واقعا گیجم کرده !!!
ببین نه انیمیشنی در کاره در چیز متحرک خاصی فقط همین فیلم هست و یک سری دکمه برای کنترل و یک چندتا عکس و این چیزا هم برای گرافیک . ولی حالا اینکه چرا اینها درست کار نمی کنن واقعا برام سوال هست.
اگر پیشنهاد دیگه ای هست گوش می کنم . واقعا کارم گیر کرده ...
بازم ممنون
فیلم ها داخل پروژه هستند یا از به صورت خارجی بارگزاری می شوند؟
 

amird

خبرگان انجمن فلش
هم داخل هستن هم از بیرون لود می شن .
گفتم که هر فایل Swf من توش یک فیلم embed شده که همین فیلم هم هست که باعث زیاد شدن فریم ها می شه . البته راه دیگه ای هم ندارم چون باید بر اساس یک زمان خاص از فیلم یک رویدادی انجام بشه .
امیدوارم بشه حلش کرد.
ممنون
 

BehrouzPc

پــــادشــاه فــلــــش
هم داخل هستن هم از بیرون لود می شن .
گفتم که هر فایل Swf من توش یک فیلم embed شده که همین فیلم هم هست که باعث زیاد شدن فریم ها می شه . البته راه دیگه ای هم ندارم چون باید بر اساس یک زمان خاص از فیلم یک رویدادی انجام بشه .
امیدوارم بشه حلش کرد.
ممنون
بهترین راه برای حل این مشکل استفاده کامل از فیلم ها به صورت خارجی (خارج از فلش) می باشد
برای قرار دادن رویداد در زمان خاص می توانید زمان جاری نمایش را دریافت کنید
برای این کنترل بیشتری داشته باشید خودتان شی ویدئو را با اکشن به پروژه اضافه کنید با این کار به راحتی بر رویداد ها کنترل دارید
بعد از اتمام هر مورد آن را unload و مورد بعد را بارگزاری کنید
روند کاری که کاملا بر مبنای تایم لاین باشد در سرعت پروژه تاثیر زیادی دارد و این روش می تواند در بهبود سرعت درصد زیادی به شما کمک نماید.

موفق و پیروز باشید
 

جدیدترین ارسال ها

بالا