জাভাতে জঞ্জাল জোগাড় করার জন্য কীভাবে বাধ্য?


225

জাভাতে আবর্জনা সংগ্রহ করা জোর করে দেওয়া কী সম্ভব, এমনকি যদি তা করাও কৃপণ হয়? আমি জানি System.gc();এবং Runtime.gc();তবে তারা কেবল জিসি করার পরামর্শ দেয়। আমি কীভাবে জিসিকে জোর করতে পারি?


30
আপনারা কেন জিসি জোর করতে হবে তার কিছু পটভূমি সরবরাহ করা সহায়ক। সাধারণত কোনও আবর্জনা সংগ্রহ করা ভাষায় স্পষ্টভাবে সংগ্রহকারীকে কল করা খারাপ অভ্যাস।
জাস্টিন ইথিয়ার

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

3
jmap -histo: লাইভ <PID> stackoverflow.com/questions/6418089/...

5
আবর্জনা সংগ্রহ করতে বাধ্য করার জন্য এখানে একটি ব্যবহারের কেস রয়েছে: আমার কাছে একটি 30 জিবি হিপ সহ একটি সার্ভার রয়েছে, যার মধ্যে সাধারণত GB 12 গিগাবাইট ডলার ব্যবহৃত হয় (M 5M অবজেক্ট)। প্রতি 5 মিনিটে, সার্ভারটি একটি জটিল কার্য সম্পাদনে মোটামুটি এক মিনিট ব্যয় করে যার মধ্যে প্রায় 35M অতিরিক্ত অবজেক্ট ব্যবহার করা হয়। একটি সম্পূর্ণ জিসি প্রায় ঘন্টা সময় বেশ কয়েকবার ট্রিগার করা হয়, অবিচ্ছিন্নভাবে জটিল কাজের সময় এবং ভিএম 10 থেকে 15 সেকেন্ডের জন্য স্থির করে দেয়। জটিল কাজটি চলছে না এমন সময় আমি পুরো জিসিকে চালাতে বাধ্য করতে পছন্দ করব; এটি তখন 40 এম এর চেয়ে 5 এম লাইভ অবজেক্টগুলিকে জাগল করে দেবে।
স্টিভ

3
@ জাস্টিনইথিয়ার এমন একটি চমত্কার স্পষ্ট ঘটনা রয়েছে যেখানে আপনি জিসিকে বাধ্য করতে পারেন, যা জাভা.লং.রেফ সম্পর্কিত রেফারেন্স টাইপ শ্রেণিবিন্যাসের সাথে জড়িত যে কোনও আচরণের পরীক্ষা করছে unit
ইলিয়াস ভ্যাসিলেনকো

উত্তর:


168

আপনার সর্বোত্তম বিকল্পটি কল করা System.gc()যা কোনও আবর্জনা সংগ্রহকারীকে কেবল কোনও ইঙ্গিত হিসাবে বলা হয় যে আপনি এটি সংগ্রহ করতে চান। আবর্জনা সংগ্রহকারী অ-নিরস্তক হওয়ায় বাধ্য ও তাত্ক্ষণিকভাবে সংগ্রহের কোনও উপায় নেই ।


28
থাকতে হবে। non-deterministic == trouble
পেসারিয়ার

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

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

আমি ভাবছিলাম যে নতুন নতুন জিনিস বরাদ্দ করে এবং তারপরে আর এগুলি উল্লেখ না করে আবর্জনা সংগ্রহকারী স্বয়ংক্রিয়ভাবে চালিত হবে
Bionix1441

@ পেটারহুডেেক বাস্তব বিশ্বের প্রয়োগগুলিতে। নেট GC.Collect()সংগ্রহ করে না। জাভা gc()হয়।
আজিহ

53

Jlibs গ্রন্থাগার আবর্জনা সংগ্রহের জন্য একটি ভাল ইউটিলিটি বর্গ হয়েছেWeakReferences অবজেক্টের সাথে একটি নিফটি সামান্য কৌশল ব্যবহার করে আবর্জনা সংগ্রহকে জোর করতে পারেন ।

জালিবগুলি থেকে রানটাইমUtil.gc () :

   /**
    * This method guarantees that garbage collection is
    * done unlike <code>{@link System#gc()}</code>
    */
   public static void gc() {
     Object obj = new Object();
     WeakReference ref = new WeakReference<Object>(obj);
     obj = null;
     while(ref.get() != null) {
       System.gc();
     }
   }

1
এই কোডটি নষ্ট হয়ে গেছে কারণ দুর্বল রেফারেন্সটি ক্লিয়ার হয়ে যাওয়ার সাথে সাথে এর রেফারেন্স দুর্বলভাবে অ্যাক্সেসযোগ্য হয়ে যায়, যা স্মৃতি থেকে পরিষ্কার হওয়ার আগে।
মার্কো তোপোলনিক

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

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

4
আপনি সম্ভবত এটির দক্ষতার সাথে তুলনা করেননি System.gc(); System.gc();, তবে এটি এটির চেয়ে আরও ভালভাবে কাজ করে কিনা তা জানতে আগ্রহী হবে। আসলে, কতবার এটি প্রিন্ট করা প্রিন্ট করা System.gc()যথেষ্ট ছিল। 2 এ পৌঁছানোর সুযোগটি বেশ পাতলা।
মার্কো টপলনিক

3
@ মারকো টপলনিক: 'কেউ নিজেরাই "জিসি সাবসিস্টেম চালাতে" বাধ্য করতে আগ্রহী না, কোনও আবর্জনা সংগ্রহ করা হয়নি' .... আসলে আমি আজ কেবল এই আচরণে আগ্রহী ছিলাম। আমি ধন্যবাদ এই উত্তর উপস্থিত ছিল। আমার উদ্দেশ্য ছিল জিসি লগ হ্যান্ডলিংয়ের ঘূর্ণনমূলক আচরণ পরীক্ষা করা এবং জিসি আউটপুটটির ফর্ম্যাট পাওয়া। এই ছোট্ট কৌশলটি আমাকে জিসি লগগুলি দ্রুত পূরণ করতে সহায়তা করেছিল।
এরিক.ওয়েথার্স

49

জিসিকে জোর করার সর্বোত্তম (কেবলমাত্র না) উপায় হ'ল একটি কাস্টম জেভিএম লেখা। আমি বিশ্বাস করি যে আবর্জনা সংগ্রাহকরা প্লাগযোগ্য হবেন তাই আপনি সম্ভবত উপলভ্য বাস্তবায়নগুলির মধ্যে একটি বেছে নিতে পারেন এবং এটি টুইট করতে পারেন।

দ্রষ্টব্য: এটি কোনও সহজ উত্তর নয়।


40
লুলজের জন্য +1 হতাশার সংবেদনশীল ব্যক্তির চেয়ে হতাশার ডিবাগিংয়ের চেয়ে ভাল কিছুই কিছুই করে না। প্রকৃতপক্ষে ব্যবহারযোগ্য উত্তর ছাড়া অন্যটি হ'ল।
jsh

40

ব্যবহার জাভা ™ ভার্চুয়াল মেশিন টুল ইন্টারফেস (জেভিএম টিআই) , ফাংশন

jvmtiError ForceGarbageCollection(jvmtiEnv* env)

"ভিএম কে জঞ্জাল সংগ্রহ করতে বাধ্য করবে" " জেভিএম টিআই জাভাটিএম প্ল্যাটফর্ম ডিবাগার আর্কিটেকচারের (জেপিডিএ) অংশ


25

হ্যাঁ আপনাকে একই পদ্ধতিতে একই সাথে পদ্ধতিতে কল করতে বাধ্য করা প্রায় সম্ভব এবং একই সাথে এইগুলি হ'ল:

System.gc ();
System.runFinalization ();

এমনকি একই সময়ে এই দুটি পদ্ধতির ব্যবহার পরিষ্কার করার জন্য যদি কেবলমাত্র একটি অবজেক্ট থাকে তবে আবর্জনা সংগ্রহকারীকে finalise()অ্যাক্সেসযোগ্য অবজেক্টের পদ্ধতিটি নির্ধারিত স্মৃতি মুক্ত করে এবং finalize()পদ্ধতিটি কী বলে তা করতে বাধ্য করে ।

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

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


10
না , এমনকি এই দুটি কমান্ড কোনও আবর্জনা সংগ্রহ করতে বাধ্য করবে না। অন্যদের দ্বারা ইতিমধ্যে উল্লিখিত হিসাবে, gc()কেবল আবর্জনা সংগ্রহ চালানোর ইঙ্গিত। runFinalizers()কেবল "বস্তুগুলিতে চূড়ান্তকরণগুলি চালিত হয় যা" ফেলে দেওয়া হয়েছে "। জিসি যদি প্রকৃতপক্ষে না চালিত হয় তবে এ জাতীয় কোনও জিনিস নাও থাকতে পারে ...
স্টিফেন হিল

এছাড়াও, System.runFinalization () কোনও কিছু চলবে কি না তার গ্যারান্টি নয়; এটা সম্ভব যে কিছুই হবে না। এটি জাভাদোকের কাছ থেকে একটি পরামর্শ : " এই পদ্ধতিটি কল করে বোঝা যায় যে জাভা ভার্চুয়াল মেশিন যে পদার্থগুলি বাতিল করা হয়েছে তবে যাদের চূড়ান্তকরণের পদ্ধতিগুলি এখনও চালানো হয়নি তার চূড়ান্ত পদ্ধতিগুলি চালনার দিকে ব্যয় করতে ব্যয় করে "
Kaan

21

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

সম্ভবত আপনি যে প্রশ্নটি জিজ্ঞাসা করতে চেয়েছিলেন তা হ'ল "আমি আবর্জনা সংগ্রহের মাধ্যমে আমার যে স্মৃতি পুনরায় দাবি করা উচিত তা কীভাবে দাবি করতে পারি?"


18

ম্যানুয়ালি জিসিকে অনুরোধ করতে (System.gc () থেকে নয়):

  1. যান: জেডিকে বিন ফোল্ডার যেমন eg সি: \ প্রোগ্রাম ফাইল \ জাভা \ jdk1.6.0_31 \ বিন
  2. Jconsole.exe খুলুন
  3. পছন্দসই স্থানীয় প্রক্রিয়া সংযোগ করুন।
  4. মেমরি ট্যাবে যান এবং জিসি সম্পাদন করুন ক্লিক করুন।

3
বিভ্রান্তিকর বিরুদ্ধে। মাউস "পারফর্ম জিসি" বোতামটি হোভার করুন। আপনি জেভিএমকে জিসি সম্পাদনের জন্য অনুরোধ করতে পারেন তবে জোর করবেন না।
কুমারান

@ পিনকেশর্মা, এটি জোর করে না । এটি একটি নিছক অনুরোধ যা সম্ভবত পুরোপুরি উপেক্ষা করা যেতে পারে।
পেসারিয়ার

@ পেসারিয়ার একটি আদর্শ বিশ্বে হ্যাঁ .. তবে আপনি যদি এটি করেন তবে আপনি দেখতে পাবেন যে তাত্ক্ষণিকভাবে স্মৃতিশক্তি বৃদ্ধি পেয়েছে ...
পিঙ্কেশ শর্মা

11

.gc ভবিষ্যতের রিলিজগুলিতে নির্মূলের প্রার্থী - একটি সান ইঞ্জিনিয়ার একবার মন্তব্য করেছিলেন যে বিশ্বের বিশেরও কম লোক আসলে .gc () ব্যবহার করতে জানেন যে - আমি গতরাতে কেন্দ্রীয় / সমালোচনামূলক কয়েক ঘন্টা কিছু কাজ করেছি SecureRandom উত্পন্ন ডেটা ব্যবহার করে ডেটা-স্ট্রাকচার, কোথাও কোথাও মাত্র ৪০,০০০ অবজেক্ট ভিএমএম ধীর হয়ে উঠবে যেন এটি পয়েন্টারের বাইরে চলে গেছে। স্পষ্টতই এটি 16-বিট পয়েন্টার টেবিলগুলিতে ক্লান্ত হয়ে পড়েছিল এবং ক্লাসিক "ব্যর্থ যন্ত্রপাতি" আচরণের প্রদর্শন করেছিল।

আমি এক্সএএমএস এবং আরও চেষ্টা করেছিলাম, যতক্ষণ না এটি প্রায় 57, এক্সএক্সএক্সএক্স কিছু না চালিত হয় ততক্ষণ কিছুটা বার বার ঝাঁকুনি দিয়েছিল। তারপরে এটি ক্যাম্প ইজি মানি-তে কোড-ব্লাটের গতি সম্পর্কে - একটি সিসি () এর পরে 57,127 থেকে 57,128 বলার পরে এটি জিসি চালিত হবে।

আপনার ডিজাইনের মৌলিক পুনরায় কাজ দরকার, সম্ভবত একটি স্লাইডিং উইন্ডো পদ্ধতির।


1
আমার কাছে এরকম কিছু রয়েছে, স্মৃতিতে প্রচুর পরিমাণে আমি সেগুলি হ্রাস করতে পারি না। আউট অফ মেমরি ব্যতিক্রম নিক্ষেপ করা হয়েছে, আমি জিসিকে জোর করে পরীক্ষা করতে চাই যদি সেখানে কোনও অনন্ত অবজেক্ট তৈরির প্রক্রিয়া থাকে বা এই সিস্টেমগুলি আমার সিস্টেম দ্বারা ব্যবহৃত হয়।

আপনি যেমন মনে করছেন আমি একই সমস্যার জন্য কাজ করছি, পিএলএস ব্যাখ্যা করে: "অসীম অবজেক্ট ক্রিয়েশন" ... ভাল গবেষণা প্রকল্প, আপনি এখানে জাভা অঞ্চলে একটি প্রশ্ন বা কিছু পোস্ট করতে পারেন (আমি এখানে নতুন সাজিয়েছি এবং নাও সাইটটি কীভাবে কাজ করে তার "ফিনাইট অটোমা" জেনে নিন) আমি গতকাল চেষ্টা করেছিলাম এবং ফাইলটি শেষ করেছিলাম 40 এখানে এবং অনুমান করুন যে পুরো জেভিএমটি 16-বিট পয়েন্টারে সীমাবদ্ধ রয়েছে, আমি বাজি ধরেছিলাম যে আমাদের যা করতে হবে তা আগ্রাসীভাবে নাল এবং ডিস্ক থেকে পড়তে হবে ...
নিকোলাস জর্ডান

সত্যি, আমি আপনাকে পাই না। তবে "অসীম অবজেক্ট ক্রিয়েশন" সম্পর্কে পরিষ্কার হওয়ার অর্থ আমি বলতে চাইছিলাম যে আমার বড় সিস্টেমে এমন কিছু কোড রয়েছে যা অবজেক্ট তৈরি করে যা স্মৃতিতে বাঁচায়, আমি এই কোডটির টুকরোটি আসলে পেতে পারি না, কেবল অঙ্গভঙ্গি !!

5
আজেবাজে কথা! এটি ব্যবহার করা উচিত যেখানে একটি সুস্পষ্ট কেস রয়েছে: টেস্টিং কোড যা দুর্বল রেফারেন্স ব্যবহার করে, যাতে আমরা নিশ্চিত করতে পারি যে দুর্বল উল্লেখগুলি পরিষ্কার হয়ে গেলে আচরণটি সঠিক কিনা correct
ইলিয়াস ভ্যাসিলেনকো

11

আপনি কমান্ড লাইন থেকে একটি জিসি ট্রিগার করতে পারেন। এটি ব্যাচ / ক্রন্টাবের জন্য দরকারী:

jdk1.7.0/bin/jcmd <pid> GC.run

দেখা :


1
রেফারেন্স সম্পর্কে কিছু ব্যাখ্যা, মন্তব্য বা বিবরণ যুক্ত করার চেষ্টা করুন
ভেলজসিজে

6

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

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


4

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


2

আপনার আবর্জনা সংগ্রহের প্রয়োজনীয়তার কারণটি যদি আপনি বর্ণনা করেন তবে ভাল হয়। আপনি যদি এসডব্লিউটি ব্যবহার করেন তবে আপনি যেমন Imageএবং Fontফ্রি মেমরির মতো সংস্থানগুলি নিষ্পত্তি করতে পারেন । এই ক্ষেত্রে:

Image img = new Image(Display.getDefault(), 16, 16);
img.dispose();

অপ্রয়োজনীয় সংস্থান নির্ধারণের জন্য সরঞ্জামগুলিও রয়েছে।


কোনও নিষ্পত্তি পদ্ধতি না থাকলে কী হবে?
আরিফ মোস্তফা

1
সম্পূর্ণরূপে প্রশ্ন সম্পর্কিত নয়! না, আমি এসডব্লিউটি ব্যবহার করছি না। আমি একটি জেএনআই পদ্ধতি কল করছি যা একটি ডেলফি নেটিভ স্তর দ্বারা একটি .NET উইন্ডো খুলবে। আমার কাছে ফোরট্রান গণনা কোরও রয়েছে যা একটি নেটিভ সি ++ স্তরের মাধ্যমে ডেটা গ্রহণ করে। এর কোন কিছুর সাথে কি সম্পর্ক আছে? আমি জিসি জোর করতে পারি নাকি? কোন? :-(
মোস্তফা জেইনালি

0

আপনি যদি স্মৃতিশক্তি হারিয়ে ফেলেছেন এবং একটি পেয়ে যাচ্ছেন তবে আপনি OutOfMemoryExceptionজাভাতে উপলব্ধ হ্যাপ স্পেসের পরিমাণ বাড়ানোর চেষ্টা করতে পারেন java -Xms128m -Xmx512mঠিক আপনার পরিবর্তে প্রোগ্রাম শুরু করে java। এটি আপনাকে প্রাথমিক স্তরের আকার 128Mb এবং সর্বোচ্চ 512Mb দেবে, যা মান 32Mb / 128Mb এর চেয়ে অনেক বেশি।


ডিফল্ট মেমরি সেটিংসটি java -Xms512M -Xmx1024M
হ'ল

0

অন্য বিকল্প হ'ল নতুন অবজেক্ট তৈরি না করা।

জাভাতে প্রয়োজনীয় জিসি হ্রাস করতে অবজেক্ট পুলিং দূরে।

অবজেক্ট পুলিং সাধারণত অবজেক্ট তৈরির চেয়ে দ্রুততর হয় না (লাইটওয়েট অবজেক্টের জন্য উদাহরণ) তবে এটি আবর্জনা সংগ্রহের চেয়ে দ্রুত is আপনি যদি 10,000 টি বস্তু তৈরি করেন এবং প্রতিটি বস্তু 16 বাইট ছিল। এটি 160,000 বাইট জিসিকে পুনরায় দাবি করতে হবে। অন্যদিকে, আপনার যদি একই সময়ে সমস্ত 10,000 এর প্রয়োজন না হয় তবে আপনি পুনরায় ব্যবহার করতে বা পুনরায় ব্যবহারের জন্য একটি পুল তৈরি করতে পারেন যা নতুন অবজেক্টগুলি নির্মাণের প্রয়োজনীয়তা এবং GC পুরানো অবজেক্টগুলির প্রয়োজনীয়তা দূর করে।

এরকম কিছু (অরক্ষিত)। এবং যদি আপনি এটি থ্রেড নিরাপদ হতে চান তবে আপনি একটি সমকালীন লিঙ্কযুক্ত কিউয়ের জন্য লিংকডলিস্টটি সরিয়ে নিতে পারেন।

public abstract class Pool<T> {
    private int mApproximateSize;
    private LinkedList<T> mPool = new LinkedList<>();

    public Pool(int approximateSize) {
        mApproximateSize = approximateSize;
    }

    public T attain() {
        T item = mPool.poll();
        if (item == null) {
            item = newInstance();
        }
        return item;
    }

    public void release(T item) {
        int approxSize = mPool.size(); // not guaranteed accurate
        if (approxSize < mApproximateSize) {
            recycle(item);
            mPool.add(item);
        } else if (approxSize > mApproximateSize) {
            decommission(mPool.poll());
        }
    }

    public abstract T newInstance();

    public abstract void recycle(T item);

    public void decommission(T item) { }

}

0

G1 GC এর সাথে ওরাকলজেডিকে 10-তে, একটি একক কল জিসিকে System.gc()পুরানো সংগ্রহটি পরিষ্কার করার কারণ করবে। আমি নিশ্চিত না যে জিসি তাত্ক্ষণিকভাবে চালায় কিনা। যাইহোক, System.gc()লুপে বহুবার ফোন করা হলেও জিসি ইয়ং কালেকশনটি পরিষ্কার করবেন না । ইয়ং কালেকশনটি পরিষ্কার করার জন্য জিসি পেতে, আপনাকে new byte[1024]কল না করে একটি লুপে (যেমন ) বরাদ্দ করতে হবে System.gc()System.gc()কোনও কারণে কল করা জিসিকে তরুণ সংগ্রহ পরিষ্কার করতে বাধা দেয়।


0

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

এটি সঠিক, কেবল অঙ্গভঙ্গি। বেশ কয়েকটি পোস্টার ইতিমধ্যে আপনার কাছে দেওয়া বেশ কয়েকটি মানসম্মত উত্তর রয়েছে। একে একে নেওয়া যাক:

  1. আমি আসলে এই টুকরো কোডটি পেতে পারি না

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

  1. আমার বড় সিস্টেমে কিছু কোড কোড অবজেক্ট তৈরি করে

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

আপনার যদি আর কোনও জিনিসের প্রয়োজন হয় না, আপনি বস্তুকে নাল বরাদ্দ করতে পারেন তবে আপনি যদি এটি ভুল হয়ে থাকেন তবে একটি নাল পয়েন্টার ব্যতিক্রম উত্পন্ন হয়। আমি বাজি ধরছি আপনি যদি এনআইও ব্যবহার করেন তবে আপনি আরও ভাল কাজ করতে পারবেন

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

হতাশ হবেন না। প্রায়শই এটির সমাধান যা আপনার ডিবিএ হ'ল কোথাও কেনা প্যাকেজ ব্যবহার করছে এবং প্রচুর ডেটা স্ট্রাকচারের জন্য মূল নকশাটি টুইট করা হয় না।

এটি খুব সাধারণ বিষয়।


-1

অবগতির জন্য

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

মাসাররাত সিদ্দিকী


শাটডাউন হুকের ত্রুটিটি হ'ল এগুলি আসলে খুব কমই কাজ করে। জোর করে সমাপ্তি কার্যকর হয় না, শূন্য-বহির্গমন প্রস্থান কোডটি কাজ করে না এবং কখনও কখনও (অফিসিয়াল) জেভিএম ততক্ষণ চালায় না যতক্ষণ আপনার চালনার প্রয়োজন হয়।
ThePyroEagle

-1

জঞ্জাল সংগ্রহকারীকে বাধ্য করার জন্য কিছু অপ্রত্যক্ষ উপায় রয়েছে। আবর্জনা সংগ্রহকারী কখন কার্যকর হবে সেই বিন্দু না হওয়া পর্যন্ত আপনাকে অস্থায়ী বস্তুগুলির সাথে গাদা পূরণ করতে হবে। আমি এমন ক্লাস তৈরি করেছি যা এইভাবে আবর্জনা সংগ্রহকারীকে বাধ্য করে:

class GarbageCollectorManager {

    private static boolean collectionWasForced;
    private static int refCounter = 0;

    public GarbageCollectorManager() {
        refCounter++;
    }

    @Override
    protected void finalize() {
        try {
            collectionWasForced = true;
            refCounter--;
            super.finalize();   
        } catch (Throwable ex) {
            Logger.getLogger(GarbageCollectorManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public int forceGarbageCollection() {
        final int TEMPORARY_ARRAY_SIZE_FOR_GC = 200_000;
        int iterationsUntilCollected = 0;
        collectionWasForced = false;

        if (refCounter < 2) 
            new GarbageCollectorManager();

        while (!collectionWasForced) {
            iterationsUntilCollected++;
            int[] arr = new int[TEMPORARY_ARRAY_SIZE_FOR_GC];
            arr = null;
        }

        return iterationsUntilCollected;
    }

}

ব্যবহার:

GarbageCollectorManager manager = new GarbageCollectorManager();
int iterationsUntilGcExecuted = manager.forceGarbageCollection();

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


"চূড়ান্ত অবধি TEMPORARY_ARRAY_SIZE_FOR_GC = 200_000;" কী?
Koray Tugay

অ্যারের আকার - জিসি কাজ শুরু করার জন্য কতগুলি অস্থায়ী অবজেক্ট (ইনটস) তৈরি করা হবে।
অগ্নিওস ভ্যাসিলিয়াসকাস

এটি কি বৈধ: পূর্ণসংখ্যায় "_"?
Koray Tugay

1
হ্যাঁ, সংখ্যাসূচক আন্ডারস্কোরগুলি জাভা এসই 7 থেকে বৈধ This এটি উদাহরণস্বরূপ যেমন এই ক্ষেত্রে যেমন হাজারে পৃথক হিসাবে এটি কার্যকর is
অগ্নিওস ভ্যাসিলিয়াসকাস

3
আপনার কোনও প্রোডাকশন সিস্টেমে এ জাতীয় কোড চালানো উচিত নয় । এই কোডটি একটি থ্রেডে চলাকালীন অন্য কোনও থ্রেডও আউটআউফ মেমরি এক্সপশন পেতে পারে, এটি প্রথমে কল করার উদ্দেশ্যটিকে পুরোপুরি রূপান্তরিত করে ....
স্টিফেন হিল

-1

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

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


দ্বিতীয় অনুচ্ছেদের প্রথম বাক্যটি একটি নন সিকুইটার
লার্নের মারকুইস

-1

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

   List<byte[]> alloc = new ArrayList<byte[]>();
   int size = 100000;
   for (int i = 0; i < 50; i++) {
        if (ref.get() == null) {
             // Test succeeded! Week referenced object has been cleared by gc.
             return;
        }
        try {
             System.gc();
        } catch (OutOfMemoryError error) {
             // OK
        }
        try {
             System.runFinalization();
        } catch (OutOfMemoryError error) {
             // OK
        }

        // Approach the jvm maximal allocatable memory threshold
        try {
             // Allocates memory.
             alloc.add(new byte[size]);

             // The amount of allocated memory is increased for the next iteration.
             size = (int)(((double)size) * 1.3);
        } catch (OutOfMemoryError error) {
             // The amount of allocated memory is decreased for the next iteration.
             size = size / 2;
        }

        try {
             if (i % 3 == 0) Thread.sleep(321);
        } catch (InterruptedException t) {
             // ignore
        }
   }

   // Test failed! 

   // Free resources required for testing
   alloc = null;

   // Try to find out who holds the reference.
   String str = null;
   try {
        str = findRefsFromRoot(ref.get(), rootsHint);
   } catch (Exception e) {
        throw new AssertionFailedErrorException(e);
   } catch (OutOfMemoryError err) {
        // OK
   }
   fail(text + ":\n" + str);

উত্স (আমি স্বচ্ছতার জন্য কিছু মন্তব্য যুক্ত করেছি): NbTestCase উদাহরণ


-1

আপনি Runtime.getRuntime().gc()ইউটিলিটি পদ্ধতিটি ব্যবহার বা ব্যবহারের চেষ্টা করতে পারেন System.gc()দ্রষ্টব্য: এই পদ্ধতিগুলি জিসি নিশ্চিত করে না। এবং তাদের ক্ষেত্রটি আপনার অ্যাপ্লিকেশনটিতে প্রোগ্রামগতভাবে পরিচালনা করার চেয়ে জেভিএমের মধ্যে সীমাবদ্ধ হওয়া উচিত।


2
অন্যান্য উত্তরে বর্ণিত হিসাবে, এই পদ্ধতিগুলি একটি (সম্পূর্ণ) আবর্জনা সংগ্রহ চালাতে বাধ্য করে না ।
ফ্লো

-2

আপনি JUnit এবং স্প্রিং ব্যবহার করছেন, প্রতিটি পরীক্ষার ক্লাসে এটি যোগ করার চেষ্টা করুন:

@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.