سؤال

لدي مُحمل فئة مخصص حتى يتمكن تطبيق سطح المكتب من بدء تحميل الفئات ديناميكيًا من خادم التطبيقات الذي أحتاج إلى التحدث إليه.لقد فعلنا ذلك لأن كمية الجرار المطلوبة للقيام بذلك أمر سخيف (إذا أردنا شحنها).لدينا أيضًا مشكلات في الإصدار إذا لم نقم بتحميل الفئات ديناميكيًا في وقت التشغيل من مكتبة AppServer.

الآن، واجهت مشكلة حيث أحتاج إلى التحدث إلى اثنين من خوادم التطبيقات المختلفة ووجدت أنه اعتمادًا على الفئات التي أقوم بتحميلها أولاً، قد أتعطل بشكل سيئ...هل هناك أي طريقة لفرض تفريغ الفصل دون قتل JVM فعليًا؟

نأمل أن يكون هذا منطقيا

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

المحلول

الطريقة الوحيدة التي يمكن من خلالها إلغاء تحميل الفصل هي أن يكون أداة تحميل الفصل المستخدمة عبارة عن مجموعة من البيانات المهملة.هذا يعني أن الإشارات إلى كل فئة على حدة وإلى أداة تحميل الفصل نفسها تحتاج إلى السير في طريق طائر الدودو.

أحد الحلول الممكنة لمشكلتك هو أن يكون لديك Classloader لكل ملف jar، وClassloader لكل من خوادم التطبيقات التي تقوم بتفويض التحميل الفعلي للفئات إلى أدوات تحميل فئة Jar محددة.بهذه الطريقة، يمكنك الإشارة إلى إصدارات مختلفة من ملف jar لكل خادم تطبيقات.

لكن هذا ليس بالأمر الهين.تسعى منصة OSGi جاهدة للقيام بذلك، حيث تحتوي كل حزمة على أداة تحميل فئة مختلفة ويتم حل التبعيات بواسطة النظام الأساسي.ربما يكون الحل الجيد هو إلقاء نظرة عليه.

إذا كنت لا ترغب في استخدام OSGI، فقد يكون أحد التطبيقات الممكنة هو استخدام مثيل واحد من JarClassloader فئة لكل ملف JAR.

وقم بإنشاء فئة MultiClassloader جديدة تعمل على توسيع Classloader.ستحتوي هذه الفئة داخليًا على مصفوفة (أو قائمة) من أدوات تحميل JarClass، وفي طريقة تعريف Class() سوف تتكرر عبر جميع أدوات تحميل الفئات الداخلية حتى يمكن العثور على تعريف، أو يتم طرح NoClassDefFoundException.يمكن توفير طريقتين للوصول لإضافة أدوات تحميل JarClass جديدة إلى الفصل.هناك العديد من التطبيقات الممكنة على الشبكة لـ MultiClassLoader، لذلك قد لا تحتاج حتى إلى كتابة تطبيق خاص بك.

إذا قمت بإنشاء مثيل MultiClassloader لكل اتصال بالخادم، فمن الممكن من حيث المبدأ أن يستخدم كل خادم إصدارًا مختلفًا من نفس الفئة.

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

نصائح أخرى

نعم، هناك طرق لتحميل الفصول الدراسية و"تفريغها" لاحقًا.تكمن الحيلة في تنفيذ أداة تحميل الفئة الخاصة بك والتي تقع بين أداة تحميل الفئة عالية المستوى (محمل فئة النظام) وأدوات تحميل الفئة لخادم (خوادم) التطبيق، ونأمل أن تقوم أدوات تحميل فئة خادم التطبيق بتفويض تحميل الفئة إلى أدوات التحميل العليا .

يتم تعريف الفئة من خلال الحزمة الخاصة بها واسمها ومحمل الفئة التي تم تحميلها في الأصل.قم ببرمجة أداة تحميل الفئة "الوكيل" وهي الأولى التي يتم تحميلها عند بدء تشغيل JVM.سير العمل:

  • يبدأ البرنامج ويتم تحميل الفئة "الرئيسية" الحقيقية بواسطة أداة تحميل فئة الوكيل هذه.
  • كل فئة يتم تحميلها بشكل طبيعي (على سبيل المثال.(ليس من خلال تنفيذ أداة تحميل فئة أخرى والتي قد تؤدي إلى كسر التسلسل الهرمي) سيتم تفويضها إلى أداة تحميل الفئة هذه.
  • مندوبي محمل فئة الوكيل java.x و sun.x إلى محمل فئة النظام (هذه لا يجب يتم تحميله من خلال أي أداة تحميل فئة أخرى غير أداة تحميل فئة النظام).
  • بالنسبة لكل فئة قابلة للاستبدال، قم بإنشاء مثيل لمحمل الفصل (الذي يقوم بالفعل بتحميل الفصل ولا يفوضه إلى محمل الفصل الأصلي) وقم بتحميله من خلال ذلك.
  • قم بتخزين الحزمة/اسم الفئات كمفاتيح ومحمل الفصل كقيم في بنية البيانات (أي.خريطة التجزئة).
  • في كل مرة يتلقى فيها مُحمل فئة الوكيل طلبًا لفئة تم تحميلها من قبل، فإنه يُرجع الفئة من مُحمل الفئة المخزنة من قبل.
  • يجب أن يكون كافيًا تحديد موقع مصفوفة البايت الخاصة بالفئة بواسطة أداة تحميل الفئة الخاصة بك (أو "حذف" زوج المفتاح/القيمة من بنية البيانات الخاصة بك) وإعادة تحميل الفئة في حالة رغبتك في تغييرها.

يتم ذلك بشكل صحيح لا ينبغي أن يأتي أ ClassCastException أو خطأ الربط إلخ.

لمزيد من المعلومات حول التسلسلات الهرمية لمحمل الفئة (نعم، هذا هو بالضبط ما تقوم بتنفيذه هنا؛-) انظر إلى "برمجة جافا المستندة إلى الخادم" بقلم تيد نيوارد - لقد ساعدني هذا الكتاب في تنفيذ شيء مشابه جدًا لما تريد.

لقد كتبت أداة تحميل فئة مخصصة، والتي يمكن من خلالها إلغاء تحميل الفئات الفردية دون استخدام أداة تحميل الفئة. محمل فئة الجرة

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

معظم الأشخاص الذين يحتاجون إلى القيام بهذا النوع من الأشياء ينتهي بهم الأمر بالاستخدام OSGi.OSGi قوي حقًا وخفيف الوزن وسهل الاستخدام بشكل مدهش،

يمكنك إلغاء تحميل ClassLoader ولكن لا يمكنك إلغاء تحميل فئات معينة.وبشكل أكثر تحديدًا، لا يمكنك إلغاء تحميل الفئات التي تم إنشاؤها في ClassLoader التي لا تقع تحت سيطرتك.

إذا كان ذلك ممكنًا، أقترح استخدام ClassLoader الخاص بك حتى تتمكن من إلغاء التحميل.

تحتوي الفئات على إشارة ضمنية قوية إلى مثيل ClassLoader الخاص بها، والعكس صحيح.يتم جمعها من القمامة كما هو الحال مع كائنات Java.دون الوصول إلى واجهة الأدوات أو ما شابه ذلك، لا يمكنك إزالة الفئات الفردية.

كما هو الحال دائمًا، يمكنك الحصول على تسرب للذاكرة.أي إشارة قوية إلى أحد الفصول الدراسية أو أداة تحميل الفصل الخاصة بك سوف تؤدي إلى تسريب الأمر برمته.يحدث هذا مع تطبيقات Sun الخاصة بـ ThreadLocal وjava.sql.DriverManager وjava.beans، على سبيل المثال.

إذا كنت تشاهد البث المباشر إذا تم تفريغ الفصل JConsole أو شيء من هذا، حاول إضافة أيضا java.lang.System.gc() في نهاية فصلك منطق التفريغ.يقوم بشكل صريح بتشغيل أداة تجميع البيانات المهملة.

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