سؤال

أنا مبرمج C ++ يحاول حاليًا العمل على Java. العمل على C ++ لدي عادة تتبع تخصيصات الذاكرة الديناميكية وتوظيف تقنيات مختلفة مثل RAII لتجنب تسرب الذاكرة. Java كما نعلم نعلم يوفر جامع القمامة (GC) لرعاية تسرب الذاكرة احصل على نهج مشابه لتلك في حين أن لغات البرمجة بدون GC ، حاول الاعتناء بالذاكرة التي تخصصها ودع GC فقط تعتني بالذاكرة التي قد تفوتك. ماذا يجب أن يكون النهج؟ ما هي الجوانب السلبية لأي منهما؟

هل كانت مفيدة؟

المحلول

لست متأكدًا مما تقصده بمحاولة الاعتناء بالذاكرة التي تخصصها بحضور GC ، لكنني سأحاول قراءة العقل.

في الأساس ، يجب ألا "تقلق" بشأن جمع ذاكرتك. إذا لم تعد تشير إلى كائنات ، فسيتم التقاطها. لا تزال تسريبات الذاكرة المنطقية ممكنة إذا قمت بإنشاء موقف يتم فيه الرجوع إلى الكائنات لبقية البرنامج الخاص بك (مثال: سجل المستمعين وعدم تسجيلهم أبدًا ، مثال null عند إزالة العناصر من النهاية).

ومع ذلك ، إذا كان لديك خلفية قوية لـ RAII ، فسوف تشعر بخيبة أمل لمعرفة أنه لا يوجد ما يعادلها مباشرة في Java. GC هي أداة من الدرجة الأولى للتعامل مع الذاكرة ، ولكن لا يوجد مضمون في موعد استدعاء (أو حتى إذا). هذا يعني أن العلاج من الدرجة الأولى المطبق على الذاكرة ليس يتم تطبيقه على أي مورد آخر ، مثل: Windows ، اتصالات قاعدة البيانات ، مآخذ ، الملفات ، بدائل التزامن ، إلخ.

نصائح أخرى

مع Java و .net (وأتصور ، معظم لغات GC'ed الأخرى) ، لا داعي للقلق كثيرًا بشأن ذاكرة الكومة على الإطلاق. ماذا أنت فعل داعي للقلق ، هي الموارد الأصلية مثل مقابض الملفات ، والمآخذ ، والبارات البدائية واجهة المستخدم الرسومية مثل الخطوط وما شابه. هؤلاء يحتاجون عمومًا إلى "التخلص" ، والذي يطلق الموارد الأصلية. (غالباً ما يتخلصون من أنفسهم على الانتهاء على أي حال ، لكن من المعتاد أن تراجع عن ذلك. التخلص من الأشياء بنفسك.)

مع GC ، عليك أن:

  • لا تزال تحرص على إصدار موارد غير ذاكرة بشكل صحيح مثل مقابض الملفات واتصالات DB.
  • تأكد من أنك لا تحتفظ بالإشارات إلى الأشياء التي لا تحتاجها بعد الآن (مثل الاحتفاظ بها في المجموعات). لأنه إذا قمت بذلك ، فلديك تسرب ذاكرة.

بصرف النظر عن ذلك ، أنت لا يمكن حقا "اعتن بالذاكرة التي تخصصها" ، ومحاولة القيام بذلك ستكون مضيعة للوقت.

من الناحية الفنية ، لا داعي للقلق بشأن التنظيف بعد تخصيصات الذاكرة نظرًا لأن جميع الكائنات مرجعة بشكل صحيح وسيعتني GC بكل شيء. في الممارسة العملية ، فإن GC مفرط النشاط سوف يؤثر سلبًا على الأداء. لذلك في حين أن Java ليس لديها ملف delete المشغل ، سوف تبلي بلاءً حسناً لإعادة استخدام الكائنات قدر الإمكان.

كما أن Java ليس لديها مدمرات لأن الأشياء ستكون موجودة حتى تصل GC إليهم ،. جافا لذلك لديها finally بنية يجب أن تستخدمها لضمان إغلاق جميع الموارد غير المرتبطة بالذاكرة (مآخذ الملفات وما إلى ذلك) عند الانتهاء منها. لا تعتمد على finalise طريقة للقيام بذلك نيابة عنك.

في Java ، تهتم GC بتخصيص الذاكرة وتحرير الذاكرة غير المستخدمة. هذا لا يعني أنه يمكنك تجاهل المشكلة.

تحرر Java GC الكائنات التي لم تتم الرجوع إليها من الجذر. هذا يعني أنه لا يزال بإمكان Java الحصول على تسرب ذاكرة إذا لم تكن حريصًا على إزالة المراجع من السياقات العالمية مثل ذاكرة التخزين المؤقت في Hashmaps العالمية ، إلخ.

إذا لم يتم الرجوع إلى أي مجموعة من الكائنات التي تشير إلى بعضها البعض من الجذر ، فإن Java GC ستحررها. أي أنه لا يعمل مع التهم المرجعية ، لذلك لا تحتاج إلى ذلك null جميع مراجع الكائنات (على الرغم من أن بعض أنماط الترميز تفضل إزالة المراجع على أنها Sonn لأنه لم يعد هناك حاجة إليها.)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top