অ্যান্ড্রয়েডে আবর্জনা সংগ্রহকারী


108

আমি অনেক অ্যান্ড্রয়েড উত্তর দেখেছি যা কিছু পরিস্থিতিতে আবর্জনা সংগ্রহকারীকে কল করার পরামর্শ দেয়।

স্মৃতি-ক্ষুধার্ত অপারেশন করার আগে অ্যান্ড্রয়েডে আবর্জনা সংগ্রহকারীকে অনুরোধ করা কি ভাল অভ্যাস? যদি তা না হয় তবে আমি কেবল OutOfMemoryত্রুটি পেলে কি ফোন করব ?

আবর্জনা সংগ্রহকারীকে অবলম্বন করার আগে আমার আরও কি জিনিস ব্যবহার করা উচিত?

উত্তর:


144

3.0 মধুচক্রের পূর্বে সংস্করণগুলির জন্য : হ্যাঁ, কল করুন System.gc()

আমি বিটম্যাপগুলি তৈরি করার চেষ্টা করেছি, তবে সর্বদা "মেমরির ত্রুটির বাইরে ভিএম" পাচ্ছিলাম। তবে, আমি যখন System.gc()প্রথম ফোন করেছি, ঠিক আছে।

বিটম্যাপগুলি তৈরি করার সময়, অ্যান্ড্রয়েড প্রায়শই মেমরির ত্রুটিগুলি থেকে ব্যর্থ হয় এবং প্রথমে আবর্জনা সংগ্রহ করার চেষ্টা করে না । অতএব, কল করুন System.gc()এবং আপনার কাছে বিটম্যাপগুলি তৈরি করার পর্যাপ্ত মেমরি রয়েছে।

যদি অবজেক্ট তৈরি করা হয়, আমি মনে করি System.gcপ্রয়োজন হলে স্বয়ংক্রিয়ভাবে ডাকা হবে তবে বিটম্যাপ তৈরির জন্য নয় । এটা ঠিক ব্যর্থ।

তাই আমি System.gc()বিটম্যাপ তৈরির আগে ম্যানুয়ালি কল করার পরামর্শ দিই ।


39
এটি হ'ল প্রাক-মধুচক্র, বিটম্যাপের ডেটা ভিএম-তে সংরক্ষণ করা হয় না এবং তাই এটি জিসিকে ট্রিগার করে না। এটি হানিকম্ব এবং তার পরে কোনও সমস্যা হওয়া উচিত নয়।
টিম্ম্ম্ম

2
@ টিম্মম্ম তবে এটি আসলে আমার সমস্যা ছিল, আমি কেবল বৃহত্তরটিকে সত্যে সেট করেছি।
লেই লেইবা

118

সাধারণভাবে বলতে গেলে কোনও আবর্জনা সংগ্রহকারীর উপস্থিতিতে জিসিকে ম্যানুয়ালি কল করা কখনই ভাল অভ্যাস নয়। একটি জিসি হিউরিস্টিক অ্যালগরিদমের চারপাশে সংগঠিত হয় যা তাদের নিজের ডিভাইসে রেখে গেলে সবচেয়ে ভাল কাজ করে। জিসি ম্যানুয়ালি কল করা প্রায়শই কর্মক্ষমতা হ্রাস করে।

মাঝেমধ্যে , কিছু তুলনামূলক বিরল পরিস্থিতিতে, কেউ দেখতে পান যে কোনও নির্দিষ্ট জিসি এটি ভুল হয়ে যায়, এবং জিসিকে একটি ম্যানুয়াল কল তার পরে কার্য সম্পাদন অনুযায়ী জিনিসগুলিতে উন্নতি করতে পারে। এর কারণ এটি একটি "নিখুঁত" জিসি বাস্তবায়ন সম্ভব নয় যা সমস্ত ক্ষেত্রে মেমরিটিকে অনুকূলভাবে পরিচালনা করবে। এই ধরনের পরিস্থিতিতে ভবিষ্যদ্বাণী করা এবং অনেক সূক্ষ্ম বাস্তবায়নের বিশদ নির্ভর করে। "ভাল অনুশীলন" হ'ল জিসিকে নিজে চালিত করা; জিসির কাছে একটি ম্যানুয়াল কল ব্যতিক্রম, যা সত্যিকারের পারফরম্যান্স ইস্যুটি যথাযথভাবে সাক্ষ্যগ্রহণের পরেই কল্পনা করা উচিত।


8
একটি ভাল প্ল্যাটফর্ম-স্বতন্ত্র উত্তরের জন্য +1। নির্বাচনের আগে কেউ অ্যান্ড্রয়েড-নির্দিষ্ট উত্তর নিয়ে আসে কিনা তা দেখার অপেক্ষা।
এইচপিক

8
আপনি যদি "পারফরম্যান্স" কে সিপিইউ দক্ষতার চেয়ে সাধারণ কিছু বোঝার অনুমতি দেন তবে আপনি যা লিখেছিলেন তার সাথে আমি একমত agree একটি অ্যান্ড্রয়েড ডিভাইসে, ব্যবহারকারীর কর্মক্ষমতা সম্পর্কে উপলব্ধি সর্বজনীন। ব্যবহারকারী উদাহরণস্বরূপ বোতাম টিপে যখন জিসি চালানো পছন্দ করতে পারেন, তাই ব্যবহারকারী জিসি সম্পর্কে সচেতন হতে পারবেন না।
রাষ্ট্রপতি জেমস কে পোলক

5
গেমগুলি প্রায়শই গুরুত্বপূর্ণ যে গেমটি চলাকালীন জিসি চলবে না (এটির জন্য সমস্ত বস্তু প্রাক-তৈরি এবং পুনর্ব্যবহারযোগ্য বা অনুরূপ হওয়া দরকার) তবে গেমটি যখন বিরতি দেওয়া হয় তখন এটি জিসির জন্য ভাল সময়।
প্যাট

4
প্রাক-মধুচক্র, বিটম্যাপের ডেটা ভিএম মেমরিতে সংরক্ষণ করা হয় না। আপনি যখন বিটম্যাপের কারণে অত্যধিক নন-ভিএম মেমরি ব্যবহার করেছেন এবং জিসি চালাবেন তখন সিস্টেমটি সনাক্ত করতে পারবেন না (যা Bitmap.finalize()পদ্ধতিগুলি চালায় যা নন-ভিএম মেমরি মুক্ত করে)। অতএব এই ক্ষেত্রে, আপনি উচিত জিসি মাথার এবং চালানোর ওভার যেতে Bitmap.recycle()বা System.gc()যেখানে যথাযথ। তবে কেবল প্রাক-মধুচক্র।
টিম্ম্ম্ম

1
@ থমাস্পর্নিন - অন্যদিকে, অ্যাপ্লিকেশন প্রোগ্রামার হিসাবে, আপনি এমন কিছু জানেন যা ওএস জানে না: যে সময়ে আপনার অ্যাপ্লিকেশনটি এখন স্মৃতি কীভাবে ব্যবহার করে তাতে বড় পরিবর্তন আনতে চলেছে , এবং এটির চেয়ে কম বিঘ্নিত হবে ভবিষ্যতে একটি স্বেচ্ছাসেবক সময় চেয়ে, এখন একটি বিরতি নিতে ব্যবহারকারীর অভিজ্ঞতা । এর অর্থ এটি অ্যাপটি কীভাবে ব্যবহৃত হচ্ছে তা বড় আকারের ট্রানজিশনে , খুব কম সময়ে কল করা বুদ্ধিমান হতে পারে । এগুলি হল বিরল অর্থে যে এক জিসি ঘন ঘন না কলিং হবে, কিন্তু হয় সাধারণ যে প্রায় কোনো উল্লেখযোগ্য অ্যাপ্লিকেশন যেমন পরিচিত-বাই-নকশা মুহূর্ত করেছে।
টুলমেকারস্টেভ

26

অ্যান্ড্রয়েড অ্যাপ্লিকেশনটিতে মেমরির বাইরে খুব সাধারণ যদি আমরা বিটম্যাপটি সঠিকভাবে পরিচালনা না করি তবে সমস্যার সমাধান হবে

if(imageBitmap != null) {
    imageBitmap.recycle();
    imageBitmap = null;
}
System.gc();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 3;
imageBitmap = BitmapFactory.decodeFile(URI, options);
Bitmap  scaledBitmap = Bitmap.createScaledBitmap(imageBitmap, 200, 200, true);
imageView.setImageBitmap(scaledBitmap);

উপরের কোডটিতে সবেমাত্র বিটম্যাপটিকে পুনর্ব্যবহার করার চেষ্টা করেছেন যা আপনাকে ব্যবহৃত মেমরির স্থানটি মুক্ত করার অনুমতি দেয়, সুতরাং স্মৃতি থেকে বেরিয়ে না আসতে পারে I আমি চেষ্টা করেছি এটি আমার জন্য কাজ করেছে।

এখনও যদি সমস্যার মুখোমুখি হন তবে আপনি এই লাইনটিও যুক্ত করতে পারেন

BitmapFactory.Options options = new BitmapFactory.Options();
options.inTempStorage = new byte[16*1024];
options.inPurgeable = true;

আরও তথ্যের জন্য এই লিঙ্কটি একবার দেখুন

https://web.archive.org/web/20140514092802/http://voices.yahoo.com/android-virtual-machine-vm-out-memory-error-7342266.html?cat=59


উল্লেখ্য: দরুন ক্ষণস্থায়ী "বিরতি দিন" জিসি সম্পাদন দ্বারা সৃষ্ট, এটা হয় না আগে এই কাজ করতে সুপারিশ প্রতিটি বিটম্যাপ বরাদ্দ।

সর্বোত্তম নকশাটি হ'ল:

  1. সমস্ত বিটম্যাপগুলি ফ্রি করুন যা এখন আর প্রয়োজন নেই , if / recycle / nullদেখানো কোড দিয়ে। (এটিতে সহায়তা করার জন্য একটি পদ্ধতি তৈরি করুন))

  2. System.gc();

  3. নতুন বিটম্যাপগুলি বরাদ্দ করুন।


19

যদি আপনি একটি আউটআফমিউরিওর পেয়ে থাকেন তবে আবর্জনা সংগ্রহকারীকে কল করতে সাধারণত দেরি হয়ে যায় ...

এখানে অ্যান্ড্রয়েড বিকাশকারী এর উদ্ধৃতি দেওয়া হয়েছে:

বেশিরভাগ সময়, টন ছোট, স্বল্প-কালীন জিনিস এবং কিছু জঞ্জাল সংগ্রহকারী, যেমন প্রজন্মের আবর্জনা সংগ্রহকারীদের মতো, আবর্জনা সংগ্রহের কারণে এই জিনিসগুলির সংগ্রহকে অনুকূলিত করা যায় যাতে অ্যাপ্লিকেশনটি প্রায়শই ব্যাহত না হয়। অ্যান্ড্রয়েড আবর্জনা সংগ্রহকারী দুর্ভাগ্যক্রমে এই ধরনের অপ্টিমাইজেশানগুলি সম্পাদন করতে সক্ষম হয় নি এবং পারফরম্যান্সের সমালোচনামূলক কোড পাথগুলিতে স্বল্প-জীবনী অবজেক্টগুলি তৈরি করা আপনার অ্যাপ্লিকেশনের পক্ষে অত্যন্ত ব্যয়বহুল।

সুতরাং আমার বোঝার জন্য, জিসি কল করার কোনও জরুরি প্রয়োজন নেই। অবজেক্টের অপ্রয়োজনীয় সৃষ্টি এড়ানোর জন্য আরও প্রচেষ্টা ব্যয় করা ভাল (লুপের অভ্যন্তরে অবজেক্ট তৈরির মতো)


6
উক্তিটি কি অন্যভাবে ব্যাখ্যা করা যায় না? খুব বেশি স্মৃতি গ্রহণ করার আগে এই বিষয়গুলি সংগ্রহ করার জন্য জিসিকে ম্যানুয়ালি কল করা দরকার।
এইচপিক

@ এইচজিপিসি: আপনার পরামর্শ অনুসারে উদ্ধৃতিটি কীভাবে ব্যাখ্যা করা যেতে পারে তা আমি দেখতে পাই না। আমি অনুমান করছি যে ডকুমেন্টেশনটি একটি স্বীকারোক্তি, স্বীকার করে যে তাদের জিসি সহজ; যখন মেমরি কম চলে, একটি সম্পূর্ণ জিসি কার্যকর করা হয়।
রাষ্ট্রপতি জেমস কে পোলক

জটিল অবজেক্টগুলি ব্যবহার করে জটিল কাঠামোগুলি এবং ফ্রেমওয়ার্কগুলির পূর্ণ ব্যবহার করা অকাল অপটিমাইজেশনের চেয়ে উন্নয়নের সময়ের আরও ভাল ব্যবহারের দিকে ঝোঁক। অপ্টিমাইজেশনের বিষয়ে উদ্বেগ করা এন্টারপ্রাইজ জাভার চেয়ে অ্যান্ড্রয়েডের মধ্যে পড়ার একটি সহজ ফাঁদ কারণ আমরা একটি মোবাইল অ্যাপ্লিকেশন কোডিংয়ের সময় অবচেতনভাবে পারফরম্যান্স সম্পর্কে ভাবতে থাকি। বিশেষ করে ফ্রেমওয়ার্ক ডেভেলপারদের, যিনি যেমন আছে কর্মক্ষমতা সম্পর্কে চিন্তা তাদের সরকারী ডকুমেন্টেশন মধ্যে যে দৃষ্টিকোণ লিক যখন তারা সতর্ক না থাকি করতে।
পার্শ্ববর্তী ফ্র্যাক্টাল

9

দেখে মনে হচ্ছে System.gc()আর্ট অ্যান্ড্রয়েড 6.0.1 নেক্সাস 5x এ কাজ করে না, সুতরাং আমি Runtime.getRuntime().gc();পরিবর্তে ব্যবহার করি ।


1
System.gc()এর জন্য একটি মোড়ক ফাংশন Runtime.getRuntime().gc()অ্যান্ড্রয়েড.googlesource.com/platform/libcore/+/…
নাথন এফ।

হ্যাঁ, উত্স এবং ডকুমেন্টেশন থেকে দেখে মনে হচ্ছে এগুলি একই, তবে প্রকৃতপক্ষে System.gc()আমার পক্ষে কাজ করে না তবে Runtime.getRuntime().gc()হয়!
ইভান

7

আমার অ্যাপ্লিকেশন প্রচুর চিত্র পরিচালনা করে এবং এটি একটি আউটআফমিরিআররের সাথে মারা যায়। এটি আমাকে সাহায্য করেছিল। ম্যানিফেস্ট.এক্সএমএল এ যুক্ত করুন

<application
....
   android:largeHeap="true"> 

9
গুগল এটি পছন্দ করে না
পেড্রো পাওলো আমোরিম

1
@ পেড্রোপোলো অ্যামেরিম কেন ব্যাখ্যা করবেন?
মাচাডো

2
আপনি কী করছেন তা নিশ্চিত না হওয়া অবধি লার্জহীপ ব্যবহার করবেন না। বড় বড় স্তূপ ব্যবহার করা আবর্জনা সংগ্রাহককে আরও কঠোর করে তোলে কারণ স্মৃতিটি পরিষ্কার করার আগে এটি প্রচুর পরিমাণে জাঙ্ক ডেটা লুপ করতে হয়।
প্রকাশ

7

সাধারণভাবে বলতে গেলে আপনার জিএসিকে স্পষ্টভাবে System.gc () দিয়ে কল করা উচিত নয়। এমনকি আইও বক্তৃতাও রয়েছে ( http://www.youtube.com/watch?v=_CruQY55HOk ) যেখানে তারা জিসি বিরতি দেওয়ার লগের অর্থ ব্যাখ্যা করে এবং যাতে তারা কখনও সিস্টেম.gc () কল না করার কথা বলে থাকে কারণ ডালভিক আরও ভাল জানেন যখন আপনি এটি করতে চেয়ে।

অন্যদিকে উপরের উত্তরে উল্লিখিত হিসাবে ইতিমধ্যে অ্যান্ড্রয়েডে জিসি প্রক্রিয়া (অন্যান্য কিছুর মতো) কখনও কখনও বগি হয়। এর অর্থ ডালভিক জিসি অ্যালগরিদমগুলি হটস্পট বা জোরোকিট জেভিএমের সাথে সমান নয় এবং কিছু উপলক্ষে জিনিসগুলি ভুল হতে পারে। বিটম্যাপ অবজেক্টগুলি বরাদ্দ করার সময় সেগুলির মধ্যে একটি। এটি একটি জটিল কারণ কারণ এটি হিপ এবং নন হিপ মেমরি ব্যবহার করে এবং কারণ মেমরির সীমাবদ্ধ ডিভাইসে বিটম্যাপ অবজেক্টের একটি শিথিল উদাহরণ আপনাকে আউটআউটমেমরির ব্যতিক্রম দিতে যথেষ্ট। সুতরাং আপনার আর এই বিটম্যাপের প্রয়োজন না হওয়ার পরে এটি কল করা সাধারণত অনেক বিকাশকারী দ্বারা পরামর্শ দেওয়া হয় এবং এমনকি কিছু লোক এটি ভাল অনুশীলন হিসাবে বিবেচিত হয়।

আরও ভাল অনুশীলনটি বিটম্যাপে .reयकल () ব্যবহার করে যেমন এই পদ্ধতিটি তৈরি করা হয়, কারণ এটি বিটম্যাপটির স্থানীয় স্মৃতি মুছে ফেলা নিরাপদ হিসাবে চিহ্নিত করে। মনে রাখবেন যে এটি খুব সংস্করণ নির্ভর, এর অর্থ এটি সাধারণত পুরানো অ্যান্ড্রয়েড সংস্করণগুলিতে প্রয়োজন হবে (প্রাক 3.0) আমি মনে করি তবে পরবর্তী সংস্করণগুলির প্রয়োজন হবে না। এছাড়াও এটি নতুন সংস্করণ ইথারে এটিকে ব্যবহার করে খুব বেশি ক্ষতি করবে না (কেবল এটি কোনও লুপ বা এমন কিছু করবেন না)। নতুন এআরটি রানটাইম এখানে অনেক পরিবর্তন হয়েছে কারণ তারা বড় অবজেক্টগুলির জন্য বিশেষ হিপ "পার্টিশন" প্রবর্তন করেছিলেন তবে আমি মনে করি এটিআরটি ইথারের সাথে এটি করতে খুব বেশি ক্ষতি হবে না।

এছাড়াও System.gc () সম্পর্কে একটি অত্যন্ত গুরুত্বপূর্ণ নোট। এই পদ্ধতিটি কোনও আদেশ নয় যা ডালভিক (বা জেভিএম) সাড়া দেওয়ার জন্য বাধ্য। ভার্চুয়াল মেশিনকে বলার মতো এটি আরও বিবেচনা করুন "ঝামেলা না হলে আপনি কি দয়া করে আবর্জনা সংগ্রহ করতে পারেন"।



3

আমি বলব না, কারণ র‌্যাম ব্যবহারের স্থিতিতে বিকাশকারী ডক্স :

...
GC_EXPLICIT

একটি সুস্পষ্ট জিসি, যেমন আপনি যখন সিসি কল করেন () (যা আপনার কল করা এড়ানো উচিত এবং পরিবর্তে জিসিকে যখন প্রয়োজন হয় তখন চালানোর উপর ভরসা করুন)।

...

আমি প্রাসঙ্গিক অংশটি সাহসের সাথে হাইলাইট করেছি।

ইউটিউব সিরিজটি দেখুন, অ্যান্ড্রয়েড পারফরম্যান্স প্যাটার্নস - এটি আপনাকে আপনার অ্যাপ্লিকেশনটির মেমরির ব্যবহার পরিচালনা করার বিষয়ে টিপস প্রদর্শন করবে (যেমন অ্যান্ড্রয়েডের পরিবর্তে ArrayMapএস এবং SparseArrayএস ব্যবহার করে HashMap) and


3

জামারিন বিকাশকারীদের জন্য দ্রুত নোট ।

আপনি যদি System.gc()জামারিনে কল করতে চান তবে অ্যান্ড্রয়েড অ্যাপগুলিতে আপনার কল করা উচিতJava.Lang.JavaSystem.Gc()


2

একটি পরে আবর্জনা সংগ্রহকারী কল করার প্রয়োজন নেই OutOfMemoryError

এটি জাভাদোক স্পষ্টভাবে বলেছে:

Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.

সুতরাং, আবর্জনা সংগ্রহকারী ত্রুটিটি তৈরি করার আগে ইতিমধ্যে মেমরি মুক্ত করার চেষ্টা করেছিল তবে এটি ব্যর্থ হয়েছিল।


8
অ্যান্ড্রয়েড জাভাদোক এটি উল্লেখ করে না এবং সম্ভবত এর প্রয়োগটি ভিন্ন। d.android.com/references/java/lang/OutOfMemoryError.html
এইচপিফিক

আপনি ঠিক বলেছেন যে এটি অ্যান্ড্রয়েডে প্রযোজ্য নয়। তবে তারপরে আবার আপনি রানটাইম ইথারে OOE পরিচালনা করতে পারবেন না যাতে এটি সত্য / সত্য না হলেও আপনি এটি সম্পর্কে বেশি কিছু করতে পারবেন না।
ইগোর Čordaš
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.