আমি 2 বছর ধরে জাভা বিকাশকারী হয়েছি।
তবে আমি আমার কোডটিতে কখনও উইক রেফারেন্স লিখিনি। আমার অ্যাপ্লিকেশনটিকে আরও দক্ষ করতে বিশেষত অ্যান্ড্রয়েড অ্যাপ্লিকেশনটিকে কীভাবে WeakReferences ব্যবহার করবেন?
আমি 2 বছর ধরে জাভা বিকাশকারী হয়েছি।
তবে আমি আমার কোডটিতে কখনও উইক রেফারেন্স লিখিনি। আমার অ্যাপ্লিকেশনটিকে আরও দক্ষ করতে বিশেষত অ্যান্ড্রয়েড অ্যাপ্লিকেশনটিকে কীভাবে WeakReferences ব্যবহার করবেন?
উত্তর:
WeakReference
অ্যান্ড্রয়েডে একটি ব্যবহার করা পুরানো জাভা ব্যবহারের চেয়ে আলাদা নয়। এখানে একটি দুর্দান্ত গাইড যা একটি বিশদ ব্যাখ্যা দেয়: দুর্বল উল্লেখগুলি বোঝা ।
আপনার যখনই কোনও জিনিসের রেফারেন্সের প্রয়োজন হয় তখন সেটিকে ব্যবহার করার বিষয়ে আপনার চিন্তা করা উচিত, তবে আবর্জনা সংগ্রহকারী থেকে সেই বিষয়টিকে রক্ষা করার জন্য আপনি সেই উল্লেখটি চান না। একটি ক্লাসিক উদাহরণ একটি ক্যাশে যা মেমরির ব্যবহার খুব বেশি হয়ে যায় (প্রায়শই প্রয়োগ করা হয় WeakHashMap
) যখন আপনি আবর্জনা সংগ্রহ করতে চান ।
চেক আউট করতে ভুলবেন হউন SoftReference
এবং PhantomReference
হিসাবে ভাল।
সম্পাদনা: টম এর সাথে ক্যাশে প্রয়োগের বিষয়ে কিছু উদ্বেগ প্রকাশ করেছে WeakHashMap
। সমস্যাগুলি প্রকাশ করার জন্য এখানে একটি নিবন্ধ রয়েছে: WeakHashMap একটি ক্যাশে নয়!
টম ঠিক বলেছেন যে ক্যাশিংয়ের কারণে নেটবিনের দুর্বল পারফরম্যান্স সম্পর্কে অভিযোগ রয়েছেWeakHashMap
।
আমি এখনও মনে করি এটির WeakHashMap
সাথে ক্যাশে প্রয়োগ করা এবং এর সাথে প্রয়োগ করা আপনার নিজের হাতে রোল করা ক্যাশের সাথে তুলনা করা ভাল শিক্ষার অভিজ্ঞতা হবে SoftReference
। আসল বিশ্বে আপনি সম্ভবত এই সমাধানগুলির কোনওটিই ব্যবহার করবেন না, কারণ অ্যাপাচি জেসিএসের মতো একটি তৃতীয় পক্ষের লাইব্রেরিটি ব্যবহার করা আরও তাত্পর্যপূর্ণ ।
WeakHashMap
ক্যাশে হিসাবে ব্যবহার করা মারাত্মক। এন্ট্রিগুলি তৈরি হওয়ার সাথে সাথে তা সরানো যেতে পারে। আপনি পরীক্ষার সময় সম্ভবত এটি ঘটবে না, তবে ব্যবহারের সময় ভাল। উল্লেখ্য, এটির মাধ্যমে নেটবিনগুলি কার্যকরভাবে 100% সিপিইউ স্টপটিতে আনা যায়।
WeakHashMap
আপনি যখন এটি পছন্দ করেন তবে এটি সঠিক পছন্দ; এমনকি যদি
[সম্পাদনা 2] এর আরও একটি ভাল উদাহরণ পেয়েছি WeakReference
। বিটম্যাপগুলি দক্ষতার সাথে প্রশিক্ষণের গাইড প্রদর্শনের ক্ষেত্রে ইউআই থ্রেড পৃষ্ঠাটি বিটম্যাপগুলি প্রসেসিং করা হচ্ছে এসিঙ্কটাস্কের একটি ব্যবহার দেখায় ।WeakReference
class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private int data = 0;
public BitmapWorkerTask(ImageView imageView) {
// Use a WeakReference to ensure the ImageView can be garbage collected
imageViewReference = new WeakReference<ImageView>(imageView);
}
// Decode image in background.
@Override
protected Bitmap doInBackground(Integer... params) {
data = params[0];
return decodeSampledBitmapFromResource(getResources(), data, 100, 100));
}
// Once complete, see if ImageView is still around and set bitmap.
@Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
এটা বলে,
ইমেজভিউয়ের দুর্বল উল্লেখটি নিশ্চিত করে যে অ্যাসিঙ্কটাস্ক চিত্র চিত্র এবং এটি যে কোনও কিছু উল্লেখ করে যা আবর্জনা সংগ্রহ করা থেকে আটকাবে না । টাস্ক শেষ হওয়ার পরে ইমেজভিউ এর আশেপাশে থাকার কোনও গ্যারান্টি নেই, সুতরাং আপনাকে পোস্টে এক্সেকিউট () এ রেফারেন্সও পরীক্ষা করতে হবে। ইমেজভিউ আর থাকতে পারে না, উদাহরণস্বরূপ, ব্যবহারকারী ক্রিয়াকলাপ থেকে দূরে সরে যায় বা যদি টাস্ক শেষ হওয়ার আগে কোনও কনফিগারেশন পরিবর্তন ঘটে।
শুভ কোডিং!
[সম্পাদনা] আমি ফেসবুক-অ্যান্ড্রয়েড-এসডিকেWeakReference
থেকে একটি দুর্দান্ত উদাহরণ খুঁজে পেয়েছি । টুলটিপপপআপ বর্গটি সরল উইজেট শ্রেণি ব্যতীত কিছুই নয় যা অ্যাঙ্কর দৃশ্যের উপরে সরঞ্জামটিপ দেখায়। আমি একটি স্ক্রিনশট ক্যাপচার।
ক্লাসটি সত্যই সহজ (প্রায় 200 টি লাইন) এবং দেখার উপযুক্ত। সেই শ্রেণিতে WeakReference
ক্লাসটি অ্যাঙ্কর ভিউয়ের রেফারেন্স রাখতে ব্যবহৃত হয়, যা নিখুঁত ধারণা দেয়, কারণ অ্যাঙ্কর ভিউয়ের পক্ষে আবর্জনা সংগ্রহ করা সম্ভব হয় এমনকি যখন কোনও সরঞ্জামদণ্ড তার অ্যাঙ্কর দৃশ্যের চেয়ে দীর্ঘস্থায়ী হয়।
শুভ কোডিং! :)
আমাকে WeakReference
ক্লাসের একটি কাজের উদাহরণ ভাগ করে দিন । এটি অ্যান্ড্রয়েড ফ্রেমওয়ার্ক উইজেট থেকে প্রাপ্ত একটি ছোট কোড স্নিপেট AutoCompleteTextView
।
সংক্ষেপে, WeakReference
ক্লাসটি উদাহরণটিতে মেমরি ফাঁস রোধ করতে অবজেক্ট ধরে রাখতে ব্যবহৃত হয় ।View
আমি শুধু কপি-এবং-পেস্ট করব PopupDataSetObserver বর্গ, যার একটি নেস্টেড ক্লাস হয় AutoCompleteTextView
। এটি সত্যিই সহজ এবং মন্তব্যগুলি ক্লাসটি ভালভাবে ব্যাখ্যা করে। শুভ কোডিং! :)
/**
* Static inner listener that keeps a WeakReference to the actual AutoCompleteTextView.
* <p>
* This way, if adapter has a longer life span than the View, we won't leak the View, instead
* we will just leak a small Observer with 1 field.
*/
private static class PopupDataSetObserver extends DataSetObserver {
private final WeakReference<AutoCompleteTextView> mViewReference;
private PopupDataSetObserver(AutoCompleteTextView view) {
mViewReference = new WeakReference<AutoCompleteTextView>(view);
}
@Override
public void onChanged() {
final AutoCompleteTextView textView = mViewReference.get();
if (textView != null && textView.mAdapter != null) {
// If the popup is not showing already, showing it will cause
// the list of data set observers attached to the adapter to
// change. We can't do it from here, because we are in the middle
// of iterating through the list of observers.
textView.post(updateRunnable);
}
}
private final Runnable updateRunnable = new Runnable() {
@Override
public void run() {
final AutoCompleteTextView textView = mViewReference.get();
if (textView == null) {
return;
}
final ListAdapter adapter = textView.mAdapter;
if (adapter == null) {
return;
}
textView.updateDropDownForFilter(adapter.getCount());
}
};
}
এবং PopupDataSetObserver
অ্যাডাপ্টার সেট করতে ব্যবহৃত হয়।
public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
if (mObserver == null) {
mObserver = new PopupDataSetObserver(this);
} else if (mAdapter != null) {
mAdapter.unregisterDataSetObserver(mObserver);
}
mAdapter = adapter;
if (mAdapter != null) {
//noinspection unchecked
mFilter = ((Filterable) mAdapter).getFilter();
adapter.registerDataSetObserver(mObserver);
} else {
mFilter = null;
}
mPopup.setAdapter(mAdapter);
}
ত্য জ্যজ্জকিজ. আমি WeakReference
অ্যান্ড্রয়েড অ্যাপ্লিকেশনটিতে কাজের উদাহরণও জানতে চেয়েছিলাম এবং এর অফিসিয়াল নমুনা অ্যাপ্লিকেশনগুলিতে আমি কিছু নমুনা খুঁজে পেতে পারি। তবে আমি তাদের কিছু ব্যবহার বুঝতে পারি নি। উদাহরণস্বরূপ, থ্রেডসাম্পল এবং প্রদর্শনবিটম্যাপ অ্যাপ্লিকেশনগুলি এর কোডটিতে ব্যবহার WeakReference
করে, তবে বেশ কয়েকটি পরীক্ষা চালানোর পরে আমি জানতে পেরেছি যে get () পদ্ধতিটি কখনই ফিরে আসে না null
, কারণ রেফারেন্সযুক্ত ভিউ অবজেক্টটি অ্যাডাপ্টারে পুনর্ব্যবহৃত হয়, তারপরে আবর্জনা সংগ্রহ করা হয়।
অন্য কয়েকটি উত্তর অসম্পূর্ণ বা অত্যধিক দীর্ঘ বলে মনে হচ্ছে। এখানে একটি সাধারণ উত্তর।
আপনি নিম্নলিখিত পদক্ষেপগুলি করতে পারেন:
WeakReference
পরিবর্তনশীল তৈরি করুনMyClass
একটি দুর্বল রেফারেন্স আছে AnotherClass
।
public class MyClass {
// 1. Create a WeakReference variable
private WeakReference<AnotherClass> mAnotherClassReference;
// 2. Set the weak reference (nothing special about the method name)
void setWeakReference(AnotherClass anotherClass) {
mAnotherClassReference = new WeakReference<>(anotherClass);
}
// 3. Use the weak reference
void doSomething() {
AnotherClass anotherClass = mAnotherClassReference.get();
if (anotherClass == null) return;
// do something with anotherClass
}
}
AnotherClass
একটি দৃ strong় রেফারেন্স আছে MyClass
।
public class AnotherClass {
// strong reference
MyClass mMyClass;
// allow MyClass to get a weak reference to this class
void someMethod() {
mMyClass = new MyClass();
mMyClass.setWeakReference(this);
}
}
MyClass
ছিল এবং AnotherClass
বি।WeakReference
হ'ল অন্য শ্রেণিটি ইন্টারফেস প্রয়োগ করে। এটি শ্রোতা / পর্যবেক্ষক প্যাটার্নে করা হয় ।// allow MyClass to get a weak reference to this class void someMethod() { mMyClass = new MyClass(); mMyClass.someMethod(this); }
??
weakreference
ক্রিয়ায় বস্তুটি নিজেই পরীক্ষা doSomething
করতে হবে । null
get
একটি "ক্যানোনিকালাইজড" ম্যাপিং হ'ল যেখানে আপনি বস্তুর একটি উদাহরণ মেমরির মধ্যে রেখেছেন এবং অন্যরা সেই নির্দিষ্ট উদাহরণটিকে পয়েন্টার বা সামস মেকানিজমের মাধ্যমে সন্ধান করে। এখানে দুর্বল উল্লেখগুলি সহায়তা করতে পারে। সংক্ষিপ্ত উত্তরটি হ'ল WeakReferences অবজেক্টগুলি আপনার সিস্টেমে অবজেক্টের পয়েন্টার তৈরি করতে ব্যবহার করা যেতে পারে এবং এখনও অবধি আবর্জনা সংগ্রাহকরা সুযোগের বাইরে চলে গেলে তাদের পুনরায় দাবি করতে দেয় । উদাহরণস্বরূপ যদি আমার কাছে এই জাতীয় কোড থাকে:
class Registry {
private Set registeredObjects = new HashSet();
public void register(Object object) {
registeredObjects.add( object );
}
}
আমি নিবন্ধিত যে কোনও বস্তুটি কখনই জিসি দ্বারা পুনরুদ্ধার করা হবে না কারণ সেটের সেটে এটির একটি উল্লেখ রয়েছে registeredObjects
। অন্যদিকে আমি যদি এটি করি:
class Registry {
private Set registeredObjects = new HashSet();
public void register(Object object) {
registeredObjects.add( new WeakReference(object) );
}
}
তারপরে যখন জিসি সেটে বস্তুগুলিকে পুনরায় দাবি করতে চায় তখন এটি সক্ষম হয়ে উঠবে। আপনি এই কৌশলটি ক্যাচিং, ক্যাটালগিং ইত্যাদির জন্য ব্যবহার করতে পারেন জিসি এবং ক্যাচিংয়ের আরও গভীরতর আলোচনার জন্য নীচে দেখুন।