জাভাতে ক্লাস আনলোড?


174

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

এখন, আমি কেবল একটি সমস্যার মুখোমুখি হয়েছি যেখানে আমাকে দুটি পৃথক অ্যাপ সার্ভারের সাথে কথা বলার দরকার পড়েছে এবং আমি দেখেছি যে আমি প্রথমে কার ক্লাস লোড করি তার উপর নির্ভর করে আমি খারাপভাবে ভেঙে যেতে পারি ... আসলে জেভিএমকে হত্যা না করে শ্রেণিটি লোড করার জন্য কি কোনও উপায় আছে?

আশা করি এটি উপলব্ধিযোগ্য


আপনার কি প্রতিটি জারের জন্য ক্লাসলোডার আছে? ক্লাস লোডার আনলোড করার জন্য কীভাবে ওএসজিআই পাত্রে সংরক্ষণাগার রয়েছে? দেখে মনে হচ্ছে ক্লাসলোডার শ্রেণিতে কোনও আনলোড এপিআই নেই?
হেটাওব্লগ

উত্তর:


190

ক্লাস লোড করা যায় এমন একমাত্র উপায় হ'ল ব্যবহৃত ক্লাসলোডার আবর্জনা সংগ্রহ করা হয়। এর অর্থ, প্রতিটি একক বর্গের জন্য এবং ক্লাসলোডারকে নিজেই ডোডোর পথে যেতে হবে।

আপনার সমস্যার একটি সম্ভাব্য সমাধান হ'ল প্রতিটি জার ফাইলের জন্য একটি ক্লাসলোডার এবং অ্যাপ্লিকেশনগুলির প্রতিটিের জন্য একটি ক্লাসলোডার যা নির্দিষ্ট জার শ্রেণিবদ্ধদের উপর ক্লাসের প্রকৃত লোডিংকে প্রতিনিধিত্ব করে। এইভাবে, আপনি প্রতিটি অ্যাপ্লিকেশন সার্ভারের জন্য জার ফাইলের বিভিন্ন সংস্করণে নির্দেশ করতে পারেন।

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

যদি আপনি ওএসজিআই ব্যবহার করতে না চান, তবে একটি সম্ভাব্য বাস্তবায়ন হ'ল প্রতিটি জেআর ফাইলের জন্য জারক্লাসলোডার শ্রেণীর একটি উদাহরণ ব্যবহার করা ।

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

আপনি যদি সার্ভারের প্রতিটি সংযোগের জন্য কোনও মাল্টিক্লাসলোডারকে ইনস্ট্যান্স করেন, নীতিগতভাবে এটি সম্ভব যে প্রতিটি সার্ভার একই শ্রেণীর আলাদা সংস্করণ ব্যবহার করে।

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


31
আরও লক্ষ করুন যে java.sun.com/docs/books/jls/second_edition/html/… অনুসারে ক্লাসগুলি নামানো একটি অপ্টিমাইজেশন এবং জেভিএম বাস্তবায়নের উপর নির্ভর করে আসলে ঘটতে পারে বা নাও পারে।

5
ওএসজিআইয়ের একটি সহজ এবং লাইটওয়েট বিকল্প হিসাবে, জেবস মডিউলগুলি চেষ্টা করুন - মডিউল প্রতি ক্লাসলোডার (জারের একটি দল) সহ শ্রেণিবদ্ধকরণ মডুলারাইজড।
ওন্দ্র ŽiŽka

42

হ্যাঁ ক্লাসগুলি লোড করার এবং সেগুলি পরে "আনলোড" করার উপায় রয়েছে। কৌশলটি হ'ল আপনার নিজের ক্লাসলোডারটি প্রয়োগ করুন যা উচ্চ স্তরের শ্রেণি লোডার (সিস্টেম বর্গ লোডার) এবং অ্যাপ্লিকেশন সার্ভারের ক্লাস লোডারগুলির মধ্যে থাকে এবং এটি আশা করা যায় যে অ্যাপ্লিকেশন সার্ভারের শ্রেণি লোডারগুলি উপরের লোডারগুলিতে শ্রেণি লোড সরবরাহ করে do ।

একটি বর্গকে তার প্যাকেজ, তার নাম এবং শ্রেণি লোডার যা এটি লোড করে দিয়ে সংজ্ঞায়িত করা হয়। একটি "প্রক্সি" ক্লাস লোডার প্রোগ্রাম করুন যা জেভিএম শুরু করার সময় লোড হয়। কর্মধারা:

  • প্রোগ্রামটি শুরু হয় এবং প্রকৃত "প্রধান" -শ্রেণীগুলি এই প্রক্সি শ্রেণিবদ্ধ দ্বারা লোড করা হয়।
  • তারপরে প্রতিটি শ্রেণি যা সাধারণত লোড হয় (যেমন অন্য শ্রেণীবদ্ধকারী প্রয়োগের মাধ্যমে নয় যা শ্রেণিবদ্ধতা ভেঙে দিতে পারে) এই শ্রেণি লোডারকে দেওয়া হবে।
  • প্রক্সি ক্লাসলোডার প্রতিনিধি java.xএবং sun.xসিস্টেম শ্রেণীবদ্ধকারীকে (এগুলি অবশ্যই সিস্টেমের ক্লাস লোডারের চেয়ে অন্য কোনও ক্লাসলোডারের মাধ্যমে লোড করা উচিত নয় )।
  • প্রতিস্থাপনযোগ্য প্রতিটি ক্লাসের জন্য, একটি শ্রেণীবদ্ধার ইনস্ট্যান্ট করুন (যা সত্যই শ্রেণিটি লোড করে এবং এটি প্যারেন্ট ক্লাসলোডারের কাছে অর্পণ করে না) এবং এর মাধ্যমে এটি লোড করুন।
  • ক্লাসগুলির প্যাকেজ / নাম কী হিসাবে ক্লাসলোডার এবং ডেটা স্ট্রাকচারে (যেমন হাশম্যাপ) মান হিসাবে সংরক্ষণ করুন।
  • প্রক্সি ক্লাসলোডার প্রতিবারের আগে লোড হওয়া শ্রেণীর জন্য একটি অনুরোধ পেয়েছে, এটি পূর্বে সঞ্চিত ক্লাস লোডার থেকে শ্রেণিটি ফেরত দেয়।
  • আপনার শ্রেণি লোডার দ্বারা কোনও শ্রেণীর বাইট অ্যারে সনাক্ত করা (বা আপনার ডেটা কাঠামো থেকে কী / মান জোড় "মুছে ফেলতে") এবং ক্লাসটি পরিবর্তন করতে চান সে ক্ষেত্রে এটি পুনরায় লোড করা যথেষ্ট should

সম্পন্ন হয়েছে, ঠিক সেখানে একটা আসা উচিত নয় ClassCastException বা LinkageError ইত্যাদি

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


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

@ dma_k ঠিক আছে, উত্তরটি ভাল, তবে আপনি উল্লেখ করেছেন এমন মূল পয়েন্টগুলি স্পর্শ করছে না।
লিঙ্কিং

@ জর্জি কি এমন কোনও বাস্তবায়ন রয়েছে যার জন্য আমরা এটি ইনস্ট্যানেট / পুনঃব্যবহার করতে পারি?
টানা স্লেজগাড়ির

1
এটি খুব সাহায্যকারী হবে, যদি আপনি নমুনা জাভা কোডটি সরবরাহ করতে পারেন T সুনির্দিষ্ট হওয়ার জন্য, আমি কীভাবে কাস্টমক্লাসলডার ব্যবহার করে ক্লাসগুলি আনলোড করব তা খুঁজছি তবে ভাগ্য নেই had
শ্রীহর্ষ grv

@ শ্রীহরশগ.আরভি আপনি কি চেষ্টা করে একটি নমুনা প্রয়োগ করেছেন?
নিয়াওমিজিয়ান

17

আমি একটি কাস্টম ক্লাসলোডার লিখেছি, সেখান থেকে ক্লাসলোডারকে জিসিিং না করে স্বতন্ত্র ক্লাসগুলি আনলোড করা সম্ভব। জার ক্লাস লোডার


একটি যাদুমন্ত্র মত কাজ করে :). একটি জার ফাইলের সমস্ত শ্রেণি ফাইল আনলোড করার কোনও পদ্ধতি আছে?
এরকসেন

দুর্ভাগ্য এই মুহূর্তে না। তবে এটি খতিয়ে দেখা হবে। ভবিষ্যতে মুক্তি হতে পারে।
কামরান

যাইহোক, আমি কিছুটা কাজ দেখতে পেয়েছি। JarClassLoaderআপনার লোড হওয়া প্রতিটি জার ফাইলের জন্য যদি আপনার কাছে একটি থাকে তবে আপনি getLoadedClasses()এটিতে কল করতে পারেন , তারপরে প্রতিটিটির উপরে পুনরাবৃত্তি করুন এবং এটি আনলোড করুন।
এরকসেন

12

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

বেশিরভাগ লোকের এই ধরণের জিনিসটি OSGi ব্যবহার করে শেষ করা উচিত । ওএসজিআই সত্যই শক্তিশালী এবং আশ্চর্যজনকভাবে হালকা ওজনের এবং সহজেই ব্যবহারযোগ্য,


7

আপনি একটি ClassLoader আনলোড করতে পারেন তবে আপনি নির্দিষ্ট ক্লাসগুলি আনলোড করতে পারবেন না। আরও সুনির্দিষ্টভাবে আপনি ক্লাসলুডারে তৈরি ক্লাসগুলি আনড করতে পারবেন না যা আপনার নিয়ন্ত্রণে নেই।

যদি সম্ভব হয় তবে আমি নিজের ক্লাসলোডার ব্যবহার করার পরামর্শ দিচ্ছি যাতে আপনি আনলোডটি করতে পারেন।


4

শ্রেণিতে তাদের ClassLoader উদাহরণের একটি অন্তর্নিহিত দৃ strong় উল্লেখ রয়েছে এবং এর বিপরীতে। এগুলি জাভা সামগ্রীর মতো সংগ্রহ করা আবর্জনা। সরঞ্জাম ইন্টারফেস বা অনুরূপ আঘাত না করে, আপনি পৃথক ক্লাস অপসারণ করতে পারবেন না।

বরাবর আপনি মেমরি ফাঁস পেতে পারেন। আপনার ক্লাসে বা শ্রেণীর লোডারগুলির কোনওরকম শক্তিশালী উল্লেখ পুরো জিনিসটি ফাঁস করবে। এটি থ্রডলোকাল, java.sql.DriverManager এবং java.beans এর সূর্যের প্রয়োগের সাথে ঘটে।


-1

আপনি যদি আনলডিং ক্লাসটি জে কনসোল বা অন্য কিছুতে কাজ করে তা সরাসরি দেখছেন, তবে java.lang.System.gc()আপনার শ্রেণিটি আনলোডিংয়ের যুক্তির শেষে যুক্ত করার চেষ্টা করুন । এটি স্পষ্টভাবে আবর্জনা সংগ্রাহককে ট্রিগার করে।


3
যত্নশীল: System.gc () জিসি কল করার প্রয়োজন নেই। এটি কেবল জেভিএমকে এটি শুরু করতে বলে, তবে এটি কার্যকর করে না। এবং IME এটি প্রায়শই GC শুরু করে না: - \
জুহ_
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.