জাভাতে কখন চূড়ান্তকরণ () পদ্ধতি বলা হয়?


330

finalize()পদ্ধতিটি কবে ডাকা হয় তা আমার জানতে হবে JVM। আমি একটি পরীক্ষা ক্লাস তৈরি করেছি যা কোনও ফাইলের মধ্যে লেখায় যখন finalize()পদ্ধতিটি ওভাররাইড করে ডাকা হয়। এটি কার্যকর করা হয় না। এটি বাস্তবায়ন না করার কারণ আমাকে কেউ বলতে পারেন?


34
পার্শ্ব নোটের মতো: চূড়ান্তকরণটি জাভা 9
রেজিস্ট্রেশন


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

উত্তর:


273

সাধারণভাবে finalize()কোনও পরিষ্কারকরণ ইত্যাদির উপর নির্ভর না করা ভাল

জাভাডোকের মতে (যা এটি পড়ার মতো হবে), এটি হ'ল:

আবর্জনা সংগ্রহকারী দ্বারা কোনও বস্তুতে কল করা হয় যখন আবর্জনা সংগ্রহ নির্ধারণ করে যে বস্তুর আর কোনও উল্লেখ নেই।

জোয়াকিম যেমন উল্লেখ করেছেন, কোনও প্রোগ্রামের জীবনে এটি কখনও না ঘটতে পারে যদি বস্তুটি সর্বদা অ্যাক্সেসযোগ্য থাকে।

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


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

113
"ব্যবহারের সর্বোত্তম পদ্ধতি নয় ... যদি না আপনার নির্দিষ্ট কিছু প্রয়োজন হয় তবে" - উহ্, এই বাক্যটি সমস্ত কিছুর 100% ক্ষেত্রে প্রযোজ্য, সুতরাং সহায়ক নয়। জোছিম সউরের উত্তরটি আরও ভাল
বিটি

1
@ জোম-বি আপনার উদাহরণ স্পষ্টকরণের জন্য সহায়ক, তবে কেবলমাত্র পেডেন্টিক হওয়ার জন্য, সম্ভবত প্রধান শ্রেণিটিতে এটি ডাকা যেতে পারে যদি প্রধান শ্রেণি একটি ডেমন-থ্রেড তৈরি করে এবং তারপরে ফিরে আসে?
টম জি

3
তাহলে পরিস্থিতিগুলি কোথায় কার্যকর finalizeহবে?
nbro

3
@ মার্ক জেরনিমাস - আসলে এটি অপ্রাসঙ্গিক। finalize()যখন একটি >> ক্লাসের নিদর্শনের সঙ্গে << আবর্জনা সংগ্রহ করা হয়, যখন না মেন মেথড বন্ধ প্রধান বর্গ জন্য উপর পদ্ধতি প্রার্থনা করা হয়। এবং তদতিরিক্ত, আবেদন শেষ হওয়ার আগেই মূল শ্রেণি আবর্জনা সংগ্রহ করতে পারে; যেমন একটি মাল্টি-থ্রেডড অ্যাপ্লিকেশন যেখানে "মূল" থ্রেড অন্য থ্রেড তৈরি করে এবং তারপরে ফিরে আসে। (অনুশীলনে, একটি অ-মানক শ্রেণিবদ্ধার প্রয়োজন হবে ....)
স্টিফেন সি

379

finalizeপদ্ধতি নামক একটি বস্তু সম্পর্কে আবর্জনা সংগ্রহ করতে যখন করা হয়। এটি আবর্জনা সংগ্রহের জন্য যোগ্য হয়ে উঠার পরে যে কোনও সময় হতে পারে।

নোট করুন এটি সম্পূর্ণরূপে সম্ভব যে কোনও বস্তু কখনও জঞ্জাল সংগ্রহ না করে (এবং এভাবে) finalize কখনও বলা হয় না)। এটি ঘটতে পারে যখন বস্তুটি কখনই সিসির জন্য যোগ্য না হয়ে যায় (কারণ এটি জেভিএম এর পুরো জীবনকালের মধ্য দিয়ে পৌঁছতে পারে) বা যখন কোনও আবর্জনা সংগ্রহ বস্তুর যোগ্য হওয়ার সময় এবং জেভিএম চলমান বন্ধ হওয়ার সময় না ঘটে (এটি প্রায়শই সরল সহ ঘটে থাকে) পরীক্ষা প্রোগ্রাম)।

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

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


2
@Rajesh। না এটি কোনও "আয়ু" বিষয় নয়। আপনি আপনার প্রোগ্রামটিকে একটি অসীম লুপে রেখে দিতে পারেন (বছরের পর বছর ধরে), এবং আবর্জনা সংগ্রাহকের প্রয়োজন না হলে এটি কখনও চালিত হবে না।
ক্রিসক্যান্ট্রেল

5
@ ভিকাস ভার্মা: নিখুঁত প্রতিস্থাপন কিছুই নয়: আপনার প্রয়োজন হবে না। আপনার শ্রেণি যদি কিছু বাহ্যিক সংস্থান (যেমন টিসিপি / আইপি সংযোগ, ফাইল ... যা জাভা জিসি হ্যান্ডেল করতে পারে না এমন কিছু পরিচালনা করে) পরিচালনা করে তবেই এটির অর্থ হবে। এই ক্ষেত্রে Closableইন্টারফেসটি (এবং এর পেছনের ধারণাটি) সম্ভবত আপনি যা চান: .close()রিসোর্সটি বন্ধ করুন / বাতিল করুন এবং আপনার শ্রেণীর ব্যবহারকারীকে সঠিক সময়ে এটির কল করতে হবে। আপনি "কেবলমাত্র বাঁচানোর জন্য" কোনও পদ্ধতি যুক্ত করতে চাইতে পারেন finalize, তবে এটি একটি সত্যিকারের স্থির চেয়ে ডিবাগিংয়ের সরঞ্জাম হিসাবে বেশি হবে (কারণ এটি যথেষ্ট নির্ভরযোগ্য নয়)।
জোছিম সউর

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

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

2
ফাইনালাইজাররা মাঝেমধ্যে দিনটি বাঁচাতে পারে ... আমার একটি তৃতীয় পক্ষের লাইব্রেরি একটি ফাইলআইপুট স্ট্রিম ব্যবহার করছে, এটি কখনও বন্ধ করবে না। আমার কোডটি লাইব্রেরির কোডকে কল করছিল এবং তারপরে ফাইলটি সরানোর চেষ্টা করেছিল, ব্যর্থ হয়ে কারণ এটি এখনও খোলা ছিল। আমাকে System.gc()ফাইলআইনপুটস্ট্রিম :: চূড়ান্তকরণ () আবেদনের জন্য কলটি বাধ্য করতে হয়েছিল, তারপরে আমি ফাইলটি সরাতে পারি।
এলিস্ট

73
protected void finalize() throws Throwable {}
  • প্রতিটি বর্গ উত্তরাধিকার সূত্রে finalize() java.lang.Object থেকে পদ্ধতিটি
  • পদ্ধতিটি আবর্জনা সংগ্রাহক দ্বারা ডাকা হয় যখন এটি স্থির করে যে কোনও বস্তুর কোনও উল্লেখের অস্তিত্ব নেই
  • অবজেক্ট ফাইনালাইজ পদ্ধতিটি কোনও ক্রিয়া সম্পাদন করে না তবে এটি কোনও শ্রেণীর দ্বারা ওভাররাইড হতে পারে
  • সাধারণত এটি জাভাবিহীন রিসোর্সগুলি পরিষ্কার করার জন্য অর্থাত্ কোনও ফাইল বন্ধ করে দেওয়া উচিত closing
  • যদি ওভাররাইড finalize()করা হয় তবে চেষ্টা-শেষের বিবৃতিটি ব্যবহার করা এবং সর্বদা কল করা ভাল প্রোগ্রামিং অনুশীলন super.finalize()। এটি অবিচ্ছিন্নভাবে ক্লাস কলিংয়ের বিষয়গুলির দ্বারা ব্যবহৃত কোনও সংস্থান বন্ধ করতে মিস করবেন না তা নিশ্চিত করার জন্য এটি একটি সুরক্ষা ব্যবস্থা

    protected void finalize() throws Throwable {
         try {
             close();        // close open files
         } finally {
             super.finalize();
         }
     }
  • finalize()আবর্জনা সংগ্রহের সময় নিক্ষিপ্ত যে কোনও ব্যতিক্রম চূড়ান্তকরণ বন্ধ করে দেয় তবে অন্যথায় উপেক্ষা করা হয়

  • finalize() কোনও বস্তুতে কখনও একাধিকবার চলবে না

থেকে উদ্ধৃত: http://www.janeg.ca/scjp/gc/finalize.html

আপনি এই নিবন্ধটি পরীক্ষা করতে পারেন:


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

3
যেহেতু রানফিনালাইজারঅনক্সিট () থ্রেড-নিরাপদ নয়, তাই রান্টটাইম.কেট রুনটাইম () যা করতে পারে তা হ'ল অ্যাডশুটডাউনহুক (নতুন থ্রেড () {সর্বজনীন শূন্য রানের () {MMMEEnclosingClass ();}}); ক্লাস এর কনস্ট্রাক্টর মধ্যে।
উস্তামান সংগীত

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

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

25

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

আপনি সম্ভবত যা চান তা হ'ল একটি সংমিশ্রণ finallyএবং একটি ক্লিনআপ পদ্ধতির, যা এইভাবে :

MyClass myObj;

try {
    myObj = new MyClass();

    // ...
} finally {

    if (null != myObj) {
        myObj.cleanup();
    }
}

20

কার্যকর জাভা, দ্বিতীয় সংস্করণ পৃষ্ঠা 27 দেখুন out আইটেম 7: চূড়ান্তকরণগুলি এড়ান

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

কোনও উত্স শেষ করতে, পরিবর্তে চেষ্টা করুন-পরিবর্তে ব্যবহার করুন:

// try-finally block guarantees execution of termination method
Foo foo = new Foo(...);
try {
    // Do what must be done with foo
    ...
} finally {
    foo.terminate(); // Explicit termination method
}

3
বা ব্যবহার-সহ-সংস্থানগুলি ব্যবহার করুন
গ্যাব্রিয়েল গার্সিয়া

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

16

finalize()জাভাতে পদ্ধতিটি কখন বলা হয়?

চূড়ান্তকরণের পদ্ধতিটি জিসি সনাক্ত করার পরে কল করা হবে যে বস্তুটি আর অ্যাক্সেসযোগ্য নয় এবং বাস্তবে এটি বস্তুর দ্বারা ব্যবহৃত স্মৃতি পুনরুদ্ধার করার আগে।

  • যদি কোনও বস্তু কখনই অ্যাক্সেসযোগ্য হয় না, finalize()তবে কখনই এটিতে ডাকা হবে না।

  • যদি জিসি না চালায় তবে finalize()কখনই ডাকা যাবে না। (সাধারণত, জিসি কেবল তখন চালিত হয় যখন জেভিএম সিদ্ধান্ত নেয় যে এটি সার্থক করার জন্য পর্যাপ্ত আবর্জনার সম্ভাবনা রয়েছে।)

  • জিসি একটি নির্দিষ্ট বস্তুর অ্যাক্সেসযোগ্য নয় তা নির্ধারণের আগে এটি একাধিক জিসি চক্র নিতে পারে। (জাভা জিসিগুলি সাধারণত "প্রজন্মের" সংগ্রহকারী ...)

  • একবার জিসি কোনও বস্তুটি অ্যাক্সেসযোগ্য এবং চূড়ান্তরূপে সনাক্ত করার পরে এটি চূড়ান্তকরণের সারিতে স্থান দেয়। চূড়ান্তকরণ সাধারণত জিসির সাথে অবিচ্ছিন্নভাবে ঘটে।

(জেভিএম স্পেকটি আসলে কোনও জেভিএমকে চূড়ান্তভাবে চালানোর অনুমতি দেয় না ... তবে শর্ত থাকে যে এটি বস্তুর দ্বারা ব্যবহৃত স্থানটি পুনরায় দাবি না করে A ।)

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

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


চূড়ান্তকরণ () পদ্ধতিটি ওভাররাইড করে যখন ডাকা হয় তখন আমি একটি পরীক্ষা ক্লাস তৈরি করি যা কোনও ফাইলে লেখেন। এটি কার্যকর করা হয় না। এটি বাস্তবায়ন না করার কারণ আমাকে কেউ বলতে পারেন?

এটি বলা শক্ত, তবে কয়েকটি সম্ভাবনা রয়েছে:

  • বস্তুটি আবর্জনা সংগ্রহ করা হয়নি কারণ এটি এখনও পৌঁছনীয়।
  • বস্তুটি আবর্জনা সংগ্রহ করা হয়নি কারণ আপনার পরীক্ষা শেষ হওয়ার আগে জিসি চলবে না।
  • জিসি দ্বারা অবজেক্টটি পাওয়া গেছে এবং জিসির দ্বারা চূড়ান্তকরণের সারিতে রাখা হয়েছে, তবে আপনার পরীক্ষা শেষ হওয়ার আগে চূড়ান্তকরণ শেষ হয় নি।

10

যেহেতু জেভিএম কর্তৃক চূড়ান্তকরণ () পদ্ধতি আহ্বানের বিষয়ে একটি অনিশ্চয়তা রয়েছে (চূড়ান্তকরণ () যা ওভাররাইড করা হবে তা কার্যকর হবে কিনা তা নিশ্চিত নয়), অধ্যয়নের উদ্দেশ্যে চূড়ান্তকরণ () বলা হলে কী ঘটে তা পর্যবেক্ষণ করার আরও ভাল উপায় হ'ল কমান্ড দ্বারা জেভিএমকে জঞ্জাল সংগ্রহ কল করতে বাধ্য করুন System.gc()

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

উদাহরণ

class Car {

    int maxspeed;

    Car() {
        maxspeed = 70;
    }

    protected void finalize() {

    // Originally finalize method does nothing, but here we override finalize() saying it to print some stmt
    // Calling of finalize is uncertain. Difficult to observe so we force JVM to call it by System.gc(); GarbageCollection

        System.out.println("Called finalize method in class Car...");
    }
}

class Bike {

    int maxspeed;

    Bike() {
        maxspeed = 50;
    }

    protected void finalize() {
        System.out.println("Called finalize method in class Bike...");
    }
}

class Example {

    public static void main(String args[]) {
        Car c = new Car();
        c = null;    // if c weren`t null JVM wouldn't be certain it's cleared or not, null means has no future use or no longer in use hence clears it
        Bike b = new Bike();
        System.gc();    // should clear c, but not b
        for (b.maxspeed = 1; b.maxspeed <= 70; b.maxspeed++) {
            System.out.print("\t" + b.maxspeed);
            if (b.maxspeed > 50) {
                System.out.println("Over Speed. Pls slow down.");
            }
        }
    }
}

আউটপুট

    Called finalize method in class Car...
            1       2       3       4       5       6       7       8       9
    10      11      12      13      14      15      16      17      18      19
    20      21      22      23      24      25      26      27      28      29
    30      31      32      33      34      35      36      37      38      39
    40      41      42      43      44      45      46      47      48      49
    50      51Over Speed. Pls slow down.
            52Over Speed. Pls slow down.
            53Over Speed. Pls slow down.
            54Over Speed. Pls slow down.
            55Over Speed. Pls slow down.
            56Over Speed. Pls slow down.
            57Over Speed. Pls slow down.
            58Over Speed. Pls slow down. 
            59Over Speed. Pls slow down.
            60Over Speed. Pls slow down.
            61Over Speed. Pls slow down.
            62Over Speed. Pls slow down.
            63Over Speed. Pls slow down.
            64Over Speed. Pls slow down.
            65Over Speed. Pls slow down.
            66Over Speed. Pls slow down.
            67Over Speed. Pls slow down.
            68Over Speed. Pls slow down.
            69Over Speed. Pls slow down.
            70Over Speed. Pls slow down.

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


10
কল System.gc();করা কোনও গ্যারান্টি নয় যে জঞ্জাল সংগ্রহটি আসলে চালিত হবে।
সাইমন ফোরসবার্গ

3
কী ধরণের সংগ্রহ চলবে তাও গ্যারান্টিযুক্ত নয় । প্রাসঙ্গিক যেহেতু বেশিরভাগ জাভা জিসিগুলি "প্রজন্মের" সংগ্রাহক।
স্টিফেন সি

5

চূড়ান্তকরণ শ্রেণি তৈরির জন্য গণনা প্রিন্ট করবে।

protected void finalize() throws Throwable {
    System.out.println("Run F" );
    if ( checkedOut)
        System.out.println("Error: Checked out");
        System.out.println("Class Create Count: " + classCreate);
}

প্রধান

while ( true) {
    Book novel=new Book(true);
    //System.out.println(novel.checkedOut);
    //Runtime.getRuntime().runFinalization();
    novel.checkIn();
    new Book(true);
    //System.runFinalization();
    System.gc();

যেমন আপনি দেখতে পারেন। নিম্নোক্ত পুটগুলি দেখায় যখন ক্লাস গণনা 36 হয় তখন প্রথমবারের মতো জিসি কার্যকর করা হয়েছিল।

C:\javaCode\firstClass>java TerminationCondition
Run F
Error: Checked out
Class Create Count: 36
Run F
Error: Checked out
Class Create Count: 48
Run F

4

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

  • চূড়ান্তকরণ অবিলম্বে বলা হয় না চূড়ান্তভাবে ফাইনালাইজার (জিসি অংশ) স্বতন্ত্রভাবে রেফারেন্সের অধরা হিসাবে মালিক করে তোলে
  • ডিফল্ট আবর্জনা সংগ্রাহক অ্যাক্সেসযোগ্য অবজেক্টগুলিকে পুল দেয়
  • চূড়ান্তভাবে একটি বাস্তবায়নের বিশদটির দিকে ইঙ্গিত করে বাল্ককে ডাকা হয় যে একটি নির্দিষ্ট পর্যায়ে আবর্জনা সংগ্রহকারী সংস্থানগুলি মুক্ত করে।
  • System.gc () কল করার ফলে প্রায়শই বস্তুগুলিকে প্রায়শই চূড়ান্ত করা হয় না, এটি কেবলমাত্র ফাইনালাইজারকে পৌঁছনীয় না হওয়া অবজেক্ট সম্পর্কে আরও দ্রুত সচেতন হওয়ার ফলস্বরূপ
  • থ্রেড ডাম্প তৈরির ফলে প্রায় সর্বদা হিপ ডাম্প বা অন্য কোনও অভ্যন্তরীণ প্রক্রিয়া সম্পাদন করার সময় হাই হ্যাপ ওভারহেডের কারণে ফাইনালাইজারটি ট্রিগার হয় trigger
  • চূড়ান্তকরণ seams হয় মেমরি প্রয়োজনীয়তা (আরও মেমরি মুক্ত) বা নির্দিষ্ট অভ্যন্তরীণ সীমা বৃদ্ধির জন্য চূড়ান্তকরণের জন্য চিহ্নিত বস্তুর তালিকা দ্বারা আবদ্ধ হতে হবে। সুতরাং যদি আপনার কাছে প্রচুর অবজেক্ট চূড়ান্ত হয় তবে চূড়ান্তকরণের পর্বটি আরও কয়েকবার এবং তার আগে শুরু করা হবে যখন কেবল কয়েকটি সংখ্যার সাথে তুলনা করা হবে
  • পরিস্থিতিগুলি ছিল একটি সিস্টেম.gc () সরাসরি চূড়ান্ত করার জন্য ট্রিগার করেছিল তবে কেবল যদি রেফারেন্সটি স্থানীয় এবং স্বল্প জীবনযাত্রার হয়। এটি প্রজন্ম সম্পর্কিত হতে পারে।

চূড়ান্ত চিন্তা

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


2

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

  1. Object বস্তুর সমস্ত উল্লেখ সুস্পষ্টভাবে নালতে সেট করা হয়েছে যেমন বস্তু = নাল
  2. অবজেক্টটি একটি ব্লকের ভিতরে তৈরি করা হয় এবং একবার সেই ব্লকের প্রস্থানটি নিয়ন্ত্রণ করার পরে রেফারেন্স সুযোগের বাইরে চলে যায়।
  3. প্যারেন্ট অবজেক্টটি নালিতে সেট করা হয়েছে, যদি কোনও বস্তু অন্য কোনও অবজেক্টের রেফারেন্স ধারণ করে এবং আপনি যখন ধারক বস্তুর রেফারেন্স নাল সেট করেন, শিশু বা এতে থাকা বস্তু স্বয়ংক্রিয়ভাবে আবর্জনা সংগ্রহের জন্য যোগ্য হয়ে ওঠে।
  4. WeakHashMap এর মাধ্যমে যদি কোনও জিনিসের কেবল লাইভ রেফারেন্স থাকে তবে তা আবর্জনা সংগ্রহের জন্য উপযুক্ত হবে।

finalধীর গণনার সময় যদি কোনও সামগ্রীর ক্ষেত্রটি বারবার ব্যবহৃত হয় এবং এর পরে কখনই বস্তুটি ব্যবহার করা হবে না, সোর্স কোডটি ক্ষেত্রটির জন্য অনুরোধ না করা অবধি অবজেক্টটি জীবিত রাখা বা জেআইটি ক্ষেত্রটি একটিতে অনুলিপি করতে পারে অস্থায়ী পরিবর্তনশীল এবং তারপরে গণনার আগে অবজেক্টটি ত্যাগ করবেন?
সুপারক্যাট

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

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

@ সুপের্যাট: জেআইটি চূড়ান্তকরণের কাজটি চালায় না, কেবল কোডটি রেফারেন্স না রাখার ব্যবস্থা করে, তবে সরাসরি এঙ্কুইয়েটিং করা উপকারী হতে পারে FinalizerReference, যাতে কোনও জিসি চক্রের দরকার হয় না তা খুঁজে পাওয়ার জন্য রেফারেন্স। সংঘটিত হওয়ার আগে-আগে সম্পর্কের বিষয়টি নিশ্চিত করতে যথেষ্ট ; যেহেতু চূড়ান্তকরণটি (প্রকৃতপক্ষে) ভিন্ন থ্রেডে চলতে পারে, তাই প্রায়শই এটি আনুষ্ঠানিকভাবে প্রয়োজনীয় necessary জাভা 9 যুক্ত করতে চলেছে Reference.reachabilityFence
হোলগার

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

2

চূড়ান্ত পদ্ধতিটি গ্যারান্টিযুক্ত নয় the এই পদ্ধতিটি তখনই বলা হয় যখন বস্তুটি সিসির জন্য যোগ্য হয়ে ওঠে। অনেকগুলি পরিস্থিতি রয়েছে যেখানে অবজেক্টগুলি আবর্জনা সংগ্রহ করা যাবে না।


3
ত্রুটিপূর্ণ. আপনি যা বলছেন তা হ'ল কোনও অ্যাক্সেস যখন অ্যাক্সেসযোগ্য হয় তখন তা চূড়ান্ত হয়। পদ্ধতিটি আসলে সংগ্রহ করা হলে এটি আসলে বলা হয়।
স্টিফেন সি

2

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

protected void finalize(){
    // This is where the finalization code is entered
}

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


1

ক্লাস যেখানে আমরা চূড়ান্ত পদ্ধতিটি ওভাররাইড করি

public class TestClass {    
    public TestClass() {
        System.out.println("constructor");
    }

    public void display() {
        System.out.println("display");
    }
    @Override
    public void finalize() {
        System.out.println("destructor");
    }
}

চূড়ান্তকরণ পদ্ধতি কল করার সম্ভাবনা

public class TestGarbageCollection {
    public static void main(String[] args) {
        while (true) {
            TestClass s = new TestClass();
            s.display();
            System.gc();
        }
    }
}

যখন মেমরিটি ডাম্প বস্তুগুলির সাথে ওভারলোড হয় তখন জিসি চূড়ান্ত পদ্ধতিটি কল করবে

রান করুন এবং কনসোলটি দেখুন, যেখানে আপনি চূড়ান্ত পদ্ধতিটি ঘন ঘন বলা হচ্ছে না, যখন মেমরিটি ওভারলোড হয়ে যায় তখন চূড়ান্ত পদ্ধতিটি কল করা হবে।


0

জাভা অবজেক্টগুলিকে চূড়ান্তকরণ () নামক একটি পদ্ধতি প্রয়োগ করতে দেয় যা কল হতে পারে।

আবর্জনা সংগ্রহকারী বস্তুটি সংগ্রহ করার চেষ্টা করলে চূড়ান্তকরণ () পদ্ধতিটি কল হয় gets

আবর্জনা সংগ্রহকারী চলমান না থাকলে, পদ্ধতিটি কল হয় না।

আবর্জনা সংগ্রহকারী যদি বস্তুটি সংগ্রহ করতে ব্যর্থ হয় এবং এটি আবার চালানোর চেষ্টা করে , দ্বিতীয়বার পদ্ধতিটি কল হয় না।

অনুশীলনে, আপনি বাস্তব প্রকল্পগুলিতে এটি ব্যবহারের পক্ষে অত্যন্ত সম্ভাবনা নেই।

কেবল মনে রাখবেন যে এটি কল নাও হতে পারে এবং অবশ্যই এটি দু'বার কল করা হবে না। চূড়ান্তকরণ () পদ্ধতিটি শূন্য বা এক সময় চলতে পারে।

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

সূত্র


0

finalize()আবর্জনা সংগ্রহের ঠিক আগে বলা হয়। যখন কোনও বস্তু সুযোগের বাইরে চলে যায় তখন এটি বলা হয় না। এর অর্থ হ'ল কখন finalize()কার্যকর করা হবে তা আপনি জানেন না ।

উদাহরণ:

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


0

Https://wiki.sei.cmu.edu/confluence/display/java/MET12-J.+Do+not+use+finalizer এ উল্লিখিত হিসাবে ,

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


-3

আরও ভাল বোঝার জন্য এই প্রোগ্রামটি চালানোর চেষ্টা করুন

public class FinalizeTest 
{       
    static {
        System.out.println(Runtime.getRuntime().freeMemory());
    }

    public void run() {
        System.out.println("run");
        System.out.println(Runtime.getRuntime().freeMemory());
    }

     protected void finalize() throws Throwable { 
         System.out.println("finalize");
         while(true)
             break;          
     }

     public static void main(String[] args) {
            for (int i = 0 ; i < 500000 ; i++ ) {
                    new FinalizeTest().run();
            }
     }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.