PDA

View Full Version : آزاد نشدن رم اشعالی توسط برنامه



doctorapp
چهارشنبه 08 اردیبهشت 1395, 13:00 عصر
درود خدمت دوستان گلم
شاید سوالم تکراری باشه اما خب شایدم مشکل خیلیا باشه
من یک فرم دارم به نام A داخل این فرم یک دکمه هست که فرم B رو با کد زیر نمایش میده
Intent intent = new Intent(A.this, B.class);
intent.addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
اکتیویتی B یک سری کارا انجام میده که تقریبا 20 مگابایت از رم گوشو اشغال میکنه مشکل اینجاست وقتی اکتیویتی و میبندم و onDestroy() اجرا میشه حافظه آزاد نمیشه.
لازم به ذکره که اکتیویتی B عکس نداره که bitmap و خالی کنی.
راهی هست که با بسته شدن اکتیویتی هر منبعی که اشغال شده شده متغیر ها چه توابع و هرچی که رم و اشغال کرده آزاد بشه؟
داخل تابع onDestroy() از دستوراتی مثل System.gc(); و Runtime.getRuntime().gc() هم استفاده کردم نمیخوام از دستور EXIT استفاده کنم که برنامه از نو اجرا بشه
لطفا کمک کنید همه دنیا رو گشتم اما به دلیل سواد پایین خودم پیزی دستگیرم نشد
ممنون

hamed9090
چهارشنبه 08 اردیبهشت 1395, 15:38 عصر
بیشتر توضیح بدید ؟؟؟ از چی استفاده کردید که 20 مگ میشه

doctorapp
چهارشنبه 08 اردیبهشت 1395, 17:42 عصر
ارتباط با سروره
چیز خاصی نداره، اونم با کلاس از نوع انسی
اینش مهم نیست حتی فرم خالی هم که نشون میدم و مثلا 2 مگ حافظه میگیره وقتی میبندم همون 2 مگ هم آزاد نمیشه!!
مگه وقتی finish میزنی نباید رم اشغال شده آزاد بشه؟ اما ظاهرا نمیشه داخل نت هم خیلی گشتم و همه میگن آزاد نمیشه اما راه حلی هم ندادن!! همه میگن system.gc بزنید!اما بازم نمیشه، خود گوگل هم گفته با زدن system.gc امکان داره تاثیری رخ نده!!
کدی یا روشی چیزی نیست؟؟
وقتی فرم اصلی مثلا 10 مگ میگیره و فرم دوم مثلا 5 مگ میشه 15 تا اما وقتی فرم 2 بسته میشه حافظه اشغالی مثلا 14 میشه!!!هیچ وقت دیگه 10 یا حتی 11 هم نمیشه گاهی اوقات هم.م 15 میمونه!!!
کمککککک بدیننن لطفاااا:افسرده:

doctorapp
چهارشنبه 08 اردیبهشت 1395, 17:45 عصر
بیشتر توضیح بدید ؟؟؟ از چی استفاده کردید که 20 مگ میشه

ارتباط با سروره
چیز خاصی نداره، اونم با کلاس از نوع انسی
اینش مهم نیست حتی فرم خالی هم که نشون میدم و مثلا 2 مگ حافظه میگیره وقتی میبندم همون 2 مگ هم آزاد نمیشه!!
مگه وقتی finish میزنی نباید رم اشغال شده آزاد بشه؟ اما ظاهرا نمیشه داخل نت هم خیلی گشتم و همه میگن آزاد نمیشه اما راه حلی هم ندادن!! همه میگن system.gc بزنید!اما بازم نمیشه، خود گوگل هم گفته با زدن system.gc امکان داره تاثیری رخ نده!!
کدی یا روشی چیزی نیست؟؟
وقتی فرم اصلی مثلا 10 مگ میگیره و فرم دوم مثلا 5 مگ میشه 15 تا اما وقتی فرم 2 بسته میشه حافظه اشغالی مثلا 14 میشه!!!هیچ وقت دیگه 10 یا حتی 11 هم نمیشه گاهی اوقات هم.م 15 میمونه!!!
کمککککک بدیننن لطفاااا:افسرده:

amirxbest
چهارشنبه 08 اردیبهشت 1395, 19:57 عصر
اول از همه لازمه که بگم جاوا به طور پیشفرض مدیریت خودکار حافظه داره.و این یکی از قابلیتهای خاص جاوا نسبت به زبانهای دیگه مثل سی پلاس پلاس هست..
و اگه کار کرده باشین دیدین که تو سی پلاس پلاس وقتی یه شی میساختیم در نهایت خودمون شی رو از بین میبردیم یا همون از حافظه خارج میکردیم...
و اینجور که من تو چند منبع معتبر جاوا خوندم میاد این چیزا رو تو حافظه نگهداری میکنه مانند پشته که اگه مجدد از به آنها نیاز شد راحت تر باشه دسترسی و سرعت و نوعی کش میکنه و هرگاه که حافظه رم کم بشه خودش به طور اتوماتیک به ترتیب پشته رم رو آزاد میکنه و دلیل ماندن در رم هم همین هست....
امیدوارم متوجه شده باشید...

doctorapp
چهارشنبه 08 اردیبهشت 1395, 20:09 عصر
اول از همه لازمه که بگم جاوا به طور پیشفرض مدیریت خودکار حافظه داره.و این یکی از قابلیتهای خاص جاوا نسبت به زبانهای دیگه مثل سی پلاس پلاس هست..
و اگه کار کرده باشین دیدین که تو سی پلاس پلاس وقتی یه شی میساختیم در نهایت خودمون شی رو از بین میبردیم یا همون از حافظه خارج میکردیم...
و اینجور که من تو چند منبع معتبر جاوا خوندم میاد این چیزا رو تو حافظه نگهداری میکنه مانند پشته که اگه مجدد از به آنها نیاز شد راحت تر باشه دسترسی و سرعت و نوعی کش میکنه و هرگاه که حافظه رم کم بشه خودش به طور اتوماتیک به ترتیب پشته رم رو آزاد میکنه و دلیل ماندن در رم هم همین هست....
امیدوارم متوجه شده باشید...


اره من با سی هم کار کردم
متوجه منظورت شدم که در پشته قرار میده اما نمیخوام در پشته قرار بگیره و پاک بشه
آیا راهی هست که بتونم پشته رو خالی کنم؟
سپاس که پاسخ دادید

doctorapp
پنج شنبه 09 اردیبهشت 1395, 17:11 عصر
من یه اکتیویتی جدید درست کردم که یه عکس رو نشون بده عکسم با کد ست میکنم با کد زیر
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.image);
img_image.setImageBitmap(bmp);

بعد داخل تابع onDestroy() از کدهای زیر استفاده کردم
((BitmapDrawable)img_image.getDrawable()).getBitma p().recycle();
img_image.setImageDrawable(null);
bmp.recycle();
System.gc();
System.gc();

اما بازم رم آزاد نشد!!!
کسی نیست به منه بی سواد کمک کنه؟:گریه::گریه:

amirxbest
پنج شنبه 09 اردیبهشت 1395, 17:19 عصر
Android keeps processes around in case the user wants to restart the app, this makes the startup phase faster. The process will not be doing anything and if memory needs to be reclaimed, the process will be killed. Don't worry about it :)

amirxbest
پنج شنبه 09 اردیبهشت 1395, 17:22 عصر
دوست عزیز طبق گفته هایی که گفتم تو اکثر سایتهای خارجی هم همینو تایید کردن.
و اینجام تو stakoverflow هم بحث شده به و گفته خود اندروید مدیریت میکنه و نگران نباشید... و برای این تو حافظه میمونه که اگه مجدد خواستین سرعت بیشتری باشه و نیاز به واکشی نباشه...
و تاکید شما بی دلیل هست فکر میکنم

doctorapp
پنج شنبه 09 اردیبهشت 1395, 20:44 عصر
دوست عزیز طبق گفته هایی که گفتم تو اکثر سایتهای خارجی هم همینو تایید کردن.
و اینجام تو stakoverflow هم بحث شده به و گفته خود اندروید مدیریت میکنه و نگران نباشید... و برای این تو حافظه میمونه که اگه مجدد خواستین سرعت بیشتری باشه و نیاز به واکشی نباشه...
و تاکید شما بی دلیل هست فکر میکنم

چون هربار اکتیویتی دوم رو ران میکنم 1 مگ 1 مگ به رم اضافه میشه!!
بعد مثلا 20 بار باز و بسته شدن اکتیویتی دوم در نهایت وقتی برمیگردی به اکتیویتی اول 40 مگ رم اشغال شده!!درصورتی که باید مثلا 2 یا 3 مگ باشه

doctorapp
پنج شنبه 09 اردیبهشت 1395, 21:02 عصر
دوست عزیز طبق گفته هایی که گفتم تو اکثر سایتهای خارجی هم همینو تایید کردن.
و اینجام تو stakoverflow هم بحث شده به و گفته خود اندروید مدیریت میکنه و نگران نباشید... و برای این تو حافظه میمونه که اگه مجدد خواستین سرعت بیشتری باشه و نیاز به واکشی نباشه...
و تاکید شما بی دلیل هست فکر میکنم
آخه میخوام دخل اکتیویتی دوم یه آدابتر باشه که 2 تا دکمه داره دکمه اول مثلا 2000 تا عکس وانت رو پشت هم نشون بده خب این 2000 تا داخل رم میمونه بعد که اکتیویتی رو ببندیم و دوباره اجرا کنیم و این بار روی دکمه دوم بزنیم 2000 تا عکس سواری نسون بده خب نمیخوام اون 2000 تاوانت داخل رم بمونه میخوام وقتی دکمه اول رو زد و 2000 تا وانت و نشون داد بعد که اکتیویتی و بست این 2000 تا وانت از رم پاک بشه و دفعه بعدی که وارد اکتیویتی دوم شد و روی دکمه دوم زد 2000 سواری داخل رم بره
آیا راهی هست که خود آدابتر این کار رو بکنه؟؟آدابترم یک imageview فقط داره که عکسا رو دونه دونه نشون میده
برای اینه اسرار دارم وقتی یک عکس و نشون دادم و اکتیویتی و بستم عکسی که باز شده بسته بشه
سپاس گذارم که پاسخ میدی دوست گلم

Rezaguitar
جمعه 10 اردیبهشت 1395, 03:28 صبح
آدابتر روی getView آیتم ها رو میاره داخل رم پس عملا 2000 تا آیتم داخل رم نخواهد بود خیالتون راحت باشه.
در مورد پر شدن رم هم ,سیستم عامل به صورت خودکار این قضیه رو هندل میکنه,شما 10 تا اکتیویتی با مصرف رم بالا درست کن , بینشون حرکت کن میبینی که بعد از مثلا پر شدن 60 مگابایت یدفعه 10 مگابایت خالی میشه.چون سیستم gc خودش مدیریت میکنه.مگر اینکه انقدر بد کد بنویسید و مرتب از مقادیر public static و ... استفاده کنید که در اون صورت کلا هیچ راه حلی نمیتونه جلوی کرش برنامه رو بگیره.

doctorapp
جمعه 10 اردیبهشت 1395, 17:24 عصر
آدابتر روی getView آیتم ها رو میاره داخل رم پس عملا 2000 تا آیتم داخل رم نخواهد بود خیالتون راحت باشه.
در مورد پر شدن رم هم ,سیستم عامل به صورت خودکار این قضیه رو هندل میکنه,شما 10 تا اکتیویتی با مصرف رم بالا درست کن , بینشون حرکت کن میبینی که بعد از مثلا پر شدن 60 مگابایت یدفعه 10 مگابایت خالی میشه.چون سیستم gc خودش مدیریت میکنه.مگر اینکه انقدر بد کد بنویسید و مرتب از مقادیر public static و ... استفاده کنید که در اون صورت کلا هیچ راه حلی نمیتونه جلوی کرش برنامه رو بگیره.

ممنونم از پاسخ گوییت دوست عزیز

HDsharp
یک شنبه 12 اردیبهشت 1395, 05:44 صبح
سلام
پیشنهاد میکنم مقاله زیر را که درباره نشت حافظه در اندروید است را مطالعه کنید.

http://androidgate.ir/165/fixing-memory-leaks-in-android-outofmemoryerror/