আপনি কেন কখনও চূড়ান্তকরণ () প্রয়োগ করবেন?


371

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

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

সুতরাং আমার প্রশ্নটি হ'ল, প্রয়োগের জন্য এমন কোন ব্যবহারের কেস রয়েছে finalize()যা ভাষার মধ্যে অন্য প্রক্রিয়া বা সিনট্যাক্সের মাধ্যমে আরও নির্ভরযোগ্যভাবে পরিচালনা করা যায় না?

দয়া করে নির্দিষ্ট পরিস্থিতি বা আপনার অভিজ্ঞতা সরবরাহ করুন, কেবল একটি জাভা পাঠ্য বইয়ের পুনরাবৃত্তি করা বা চূড়ান্তকরণের উদ্দেশ্যে ব্যবহার যথেষ্ট নয়, কারণ এই প্রশ্নের উদ্দেশ্য নয়।


এইচআই চূড়ান্তকরণ () পদ্ধতিটি এখানে খুব ভালভাবে ব্যাখ্যা করেছেন howtodoinjava.com/2012/10/31/…
সমীর কাজী

2
বেশিরভাগ অ্যাপ্লিকেশন এবং লাইব্রেরি কোড কখনই ব্যবহার করবে না finalize()। যাইহোক, প্ল্যাটফর্ম লাইব্রেরি কোড , যেমন SocketInputStream, কলারের পক্ষে নেটিভ রিসোর্স পরিচালনা করে, রিসোর্স ফাঁসের ঝুঁকি হ্রাস করার চেষ্টা করে (বা PhantomReferenceপরে যুক্ত করা হয়েছে এমন সমতুল্য প্রক্রিয়াগুলি ব্যবহার করে ।) সুতরাং বাস্তুতন্ত্র তাদের প্রয়োজন যদিও 99.9999% বিকাশকারী কখনই একটি লিখবেন না।
ব্রায়ান গয়েটজ

উত্তর:


231

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

বাস্তবায়ন finalize()করতে close()আপনি সনাক্ত এটা কাজ করা হয়েছে প্রক্রিয়াকরণ। stderrবগি কলারের পরে আপনি পরিষ্কার করছেন এমন কোনও বিষয় হতে পারে point

এটি একটি ব্যতিক্রমী / বগি পরিস্থিতিতে অতিরিক্ত সুরক্ষা সরবরাহ করে। প্রত্যেক কলকারী সঠিক try {} finally {}জিনিসগুলি প্রতিবার করতে যাচ্ছেন না । দুর্ভাগ্যজনক, তবে বেশিরভাগ পরিবেশে সত্য।

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

আমি দেখি যে জাভা 9 হিসাবে, Object.finalize()অবচিত হয়ে গেছে! তারা আমাদের দিকে java.lang.ref.Cleanerএবং java.lang.ref.PhantomReferenceবিকল্প হিসাবে নির্দেশ করে ।


44
কেবলমাত্র নিশ্চিত হয়ে নিন যে কোনও ব্যতিক্রম চূড়ান্তভাবে () দ্বারা ছুঁড়ে দেওয়া হয় না, বা আবর্জনা সংগ্রহকারী সেই বস্তুর সাফাই অবিরত করবে না এবং আপনি একটি স্মৃতি ফাঁস পাবেন।
স্কাফম্যান 16

17
চূড়ান্তকরণ কল করার গ্যারান্টিযুক্ত নয়, সুতরাং এটি কোনও সংস্থান প্রকাশের উপর নির্ভর করবে না।
ফ্লিক করুন

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

4
আপনার প্রস্তাবটি দীর্ঘদিন ধরে লোকেদের বাগগুলি লুকিয়ে রাখতে পারে (কাছে ডাকা নয়)। আমি এটি করার সুপারিশ করব না।
kohlerm

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

174

finalize()জেভিএম-এর জন্য একটি ইঙ্গিত যা অনির্দিষ্ট সময়ে আপনার কোডটি কার্যকর করা ভাল nice আপনি কোডটি রহস্যজনকভাবে চালাতে ব্যর্থ হতে চাইলে এটি ভাল।

চূড়ান্তকরণে গুরুত্বপূর্ণ কিছু করা (মূলত লগিং ব্যতীত অন্য কিছু) তিনটি পরিস্থিতিতেও ভাল:

  • আপনি জুয়া খেলতে চান যে অন্যান্য চূড়ান্ত বস্তুগুলি এখনও এমন অবস্থায় থাকবে যাতে আপনার বাকি প্রোগ্রামটি বৈধ বলে মনে করে।
  • চূড়ান্তকরণের পরে তারা সঠিকভাবে আচরণ করে তা নিশ্চিত করার জন্য আপনি চূড়ান্তকরণকারী আপনার সমস্ত শ্রেণীর সমস্ত পদ্ধতিতে প্রচুর চেকিং কোড যুক্ত করতে চান।
  • আপনি দুর্ঘটনাক্রমে চূড়ান্ত বস্তুগুলিকে পুনরুত্থিত করতে চান এবং কেন তারা কাজ করেন না এবং / বা অবশেষে প্রকাশিত হওয়ার পরে তারা কেন চূড়ান্ত হয় না তা বোঝার চেষ্টা করার জন্য অনেক সময় ব্যয় করতে পারেন।

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

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

দাবি অস্বীকার: আমি অতীতে একটি জেভিএম বাস্তবায়নে কাজ করেছি। আমি চূড়ান্তকারীদের ঘৃণা করি।


76
চরম বিদ্রূপ বিচারের জন্য জোরদার
অনুমান 17

32
এটি প্রশ্নের উত্তর দেয় না; এটি কেবল finalize()কোনও কারণ না দিয়েই সমস্ত ত্রুটিগুলি বলেছেন যে কেউ সত্যই এটি ব্যবহার করতে চাইবে।
যান্ত্রিক শামুক

1
@ সুপের্যাট: ফ্যান্টম রেফারেন্সগুলি (এই বিষয়টির জন্য সমস্ত রেফারেন্স) জাভা 2
স্টিভ জেসপ

1
@ সুপের্যাট: দুঃখিত হ্যাঁ, "রেফারেন্স" দ্বারা আমি বোঝাতে চেয়েছিলাম java.lang.ref.Referenceএবং এর সাবক্লাসগুলি। জাভা 1 এর ভেরিয়েবলগুলি রয়েছে :-) এবং হ্যাঁ, এটির ফাইনালাইজারগুলিও ছিল।
স্টিভ জেসপ

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

58

একটি সহজ নিয়ম: চূড়ান্তকারী কখনও ব্যবহার করবেন না।

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

ব্রায়ান গয়েটসের একটি নিবন্ধ থেকে :

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


46

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


35

আমি 1998 সাল থেকে পেশাদারভাবে জাভা করছি, এবং আমি কখনও প্রয়োগ করিনি finalize()। না একবার.


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

2
@ ইনফ্যান্টপ্রো'আরবিন্দ 'কলিং চূড়ান্তকরণ বস্তুটি সরিয়ে দেয় না। এটি এমন একটি পদ্ধতি যা আপনি প্রয়োগ করেন যা JVM কল করতে পছন্দ করতে পারে এবং কখন এটি আবর্জনা আপনার অবজেক্ট সংগ্রহ করে।
পল টমবলিন

@ পলটম্বলিন, ওহোক এই বিশদটির জন্য ধন্যবাদ। এডিএফ-তে কোনও পৃষ্ঠা সতেজ করার কোনও পরামর্শ?
ইনফ্যান্টপ্রো'আরবিন্দ '

@ ইনফ্যান্টপ্রো'আরবিন্দ 'ধারণা নেই, কখনও এডিএফ ব্যবহার করেননি।
পল টমলিন

28

গৃহীত উত্তরটি ভাল, আমি কেবল এটি যুক্ত করতে চেয়েছিলাম যে এখন এটিকে ব্যবহার না করেই চূড়ান্তকরণের কার্যকারিতাটি পাওয়ার একটি উপায় রয়েছে।

"রেফারেন্স" ক্লাস দেখুন। দুর্বল রেফারেন্স, ফ্যান্টম রেফারেন্স এবং নরম রেফারেন্স।

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

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

public void finalize() {
  ref1 = null;
  ref2 = null;
  othercrap = null;
}

এটি এমন একটি লক্ষণ যা তারা জানত না যে তারা কী করছে। "পরিষ্কার করা" এর মতো কার্যত কখনই প্রয়োজন হয় না। ক্লাসটি যখন GC'd হয়, এটি স্বয়ংক্রিয়ভাবে সম্পন্ন হয়।

যদি আপনি এই জাতীয় কোডটি একটি চূড়ান্ত রূপে খুঁজে পান তবে এটির নিশ্চয়তা রয়েছে যে এটি লিখেছেন সে ব্যক্তি বিভ্রান্ত হয়েছিল।

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

এটি "দ্রুত" জিনিসগুলি পরিষ্কার করার জন্য কখনও ব্যবহার করা উচিত নয়।


3
ফ্যান্টম রেফারেন্সগুলি কোন বিষয়গুলি মুক্ত করা হচ্ছে তার উপর নজর রাখার একটি ভাল উপায় I
বিল মিশেল

2
আমি কখনও শুনেছি "দুর্বল রেফারেন্স" এর সর্বোত্তম ব্যাখ্যা প্রদানের জন্য উত্সাহ দেওয়া।
sscarduzio

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

27

আপনি এগুলি কী তৈরি করতে পারবেন তা আমি নিশ্চিত নই, তবে ...

itsadok@laptop ~/jdk1.6.0_02/src/
$ find . -name "*.java" | xargs grep "void finalize()" | wc -l
41

সুতরাং আমি অনুমান করি যে সূর্যের কয়েকটি ক্ষেত্রে এটি ব্যবহার করা উচিত they


12
আমার ধারণা, এটি "সূর্য বিকাশকারী কি সর্বদা সঠিক হবে" এর একটি প্রশ্ন?
কোডেরিপার

13
কিন্তু এই ব্যবহারগুলির মধ্যে কতটি finalizeপ্রকৃতপক্ষে এটি ব্যবহার না করে কেবল সমর্থন বাস্তবায়ন বা পরীক্ষার জন্য ?
যান্ত্রিক শামুক

আমি উইন্ডোজ ব্যবহার করি উইন্ডোজে আপনি কীভাবে একই জিনিসটি করবেন?
gparyani

2
@damryfbfnetsi: ACK (ইনস্টল করার চেষ্টা করুন beyondgrep.com প্রণালী দ্বারা) chocolatey.org/packages/ack । অথবা ফাইলগুলির মধ্যে একটি সাধারণ ফাইন্ড বৈশিষ্ট্যটি ব্যবহার করুন $FAVORITE_IDE
ব্রায়ান ক্লাইন

21
class MyObject {
    Test main;

    public MyObject(Test t) {    
        main = t; 
    }

    protected void finalize() {
        main.ref = this; // let instance become reachable again
        System.out.println("This is finalize"); //test finalize run only once
    }
}

class Test {
    MyObject ref;

    public static void main(String[] args) {
        Test test = new Test();
        test.ref = new MyObject(test);
        test.ref = null; //MyObject become unreachable,finalize will be invoked
        System.gc(); 
        if (test.ref != null) System.out.println("MyObject still alive!");  
    }
}

====================================

ফলাফল:

This is finalize

MyObject still alive!

=====================================

সুতরাং আপনি চূড়ান্ত পদ্ধতিতে একটি অ্যাক্সেসযোগ্য নজির পৌঁছনীয় করতে পারেন।


21
কোনও কারণে, এই কোডটি আমাকে জম্বি চলচ্চিত্রগুলির সম্পর্কে ভাবতে বাধ্য করে। আপনি আপনার বস্তুর জিসি করুন এবং তারপরে এটি আবার উঠে দাঁড়ায় ...
স্টিভেহা

উপরে ভাল কোড। আমি ভাবছিলাম কীভাবে এখনই আবার জিনিসটি পুনরায় যোগাযোগযোগ্য করে তুলবেন।
lwpro2

15
না, উপরে খারাপ কোড রয়েছে। চূড়ান্তকরণ কেন খারাপ তা এটির একটি উদাহরণ।
টনি

মনে রাখবেন যে অনুরোধ করা System.gc();কোনও গ্যারান্টি নয় যে আবর্জনা সংগ্রহকারী আসলে চলবে। হিপ ক্লিনআপ করা জিসির সম্পূর্ণ বিচক্ষণতা (সম্ভবত এখনও যথেষ্ট পরিমাণে ফ্রি হ্যাপ রয়েছে, সম্ভবত খুব বেশি খণ্ডিত নয়, ...)। সুতরাং এটি কেবল প্রোগ্রামার দ্বারা একটি বিনীত অনুরোধ "দয়া করে, আপনি কি আমাকে শুনতে এবং চালাতে পারেন?" এবং কোনও কমান্ড নয় "এখন যেমন আমি বলি তেমন দৌড়!" ভাষাগত শব্দ ব্যবহারের জন্য দুঃখিত তবে এটি জেভিএমের জিসি কীভাবে কাজ করে ঠিক তা বলে।
রোল্যান্ড

10

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

আমি জাভাতে 1.0 আলফা 3 (1995) থেকে প্রোগ্রামিং করছি এবং আমি এখনও কোনও কিছুর জন্য চূড়ান্ত করতে ওভাররাইড করতে পারি নি ...


6

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


5

উপরের উত্তরের একটি পয়েন্ট হাইলাইট করার জন্য: একক জিসি থ্রেডে ফাইনালাইজারগুলি কার্যকর করা হবে। আমি একটি বড় সান ডেমো শুনেছি যেখানে বিকাশকারীরা কিছু চূড়ান্তকারীদের সাথে একটি ছোট ঘুম জুড়েছিল এবং ইচ্ছাকৃতভাবে তার হাঁটুতে অন্যথায় অভিনব 3 ডি ডেমো নিয়ে এসেছিল।

পরীক্ষা-এনভিও ডায়াগনস্টিক্সের সম্ভাব্য ব্যতিক্রম ছাড়া, এড়ানো সেরা।

জাভাতে একেলের থিংকিং এর একটি ভাল বিভাগ রয়েছে।


4

হুঁ, আমি এটি একবার ব্যবহার করে এমন বস্তু পরিষ্কার করতে ব্যবহার করেছি যা বিদ্যমান পুলে ফেরানো হচ্ছে না।

এগুলি অনেকটা পার হয়ে গেছে, সুতরাং কখন নিরাপদে সেগুলি পুলে ফিরতে পারে তা বলা অসম্ভব। সমস্যাটি হ'ল এটি আবর্জনা সংগ্রহের সময় একটি বিশাল জরিমানা প্রবর্তন করেছিল যা বস্তুগুলিকে পুলিংয়ের চেয়ে কোনও সঞ্চয় থেকে বেশি ছিল। পুরো পুলটি ছিঁড়ে ফেলার, সবকিছুকে গতিময় করে তোলার আগে এটি প্রায় এক মাসের জন্য উত্পাদিত হয়েছিল production


4

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

এটি একটি জেডিকে 1.5 ছিল যা এখনও ব্যাপক ব্যবহারে রয়েছে।

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


3

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

অনেক ডেটাবেস ড্রাইভার তাদের বিকাশ এবং সংযোগ বাস্তবায়নে এটি বিকাশকারীদের বিরুদ্ধে কিছুটা সুরক্ষা দেওয়ার জন্য করেন যা তাদের কাছে কল করতে ভুলে যায়।


2

সম্পাদনা: ঠিক আছে, এটি আসলে কাজ করে না। আমি এটি বাস্তবায়ন করেছি এবং ভেবেছিলাম এটি যদি কখনও কখনও ব্যর্থ হয় তবে তা আমার পক্ষে ঠিক আছে তবে এটি চূড়ান্তকরণের পদ্ধতিটিকে এককবারও ডাকেনি।

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

@Override
public void finalize()
{
    try {saveCache();} catch (Exception e)  {e.printStackTrace();}
}

public void saveCache() throws FileNotFoundException, IOException
{
    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("temp/cache.tmp"));
    out.writeObject(cache);
}

আমি মনে করি একটি ক্যাশে (যে ধরণের আপনি ডিস্কে ফ্লাশ করবেন) এর একটি ভাল উদাহরণ। এমনকি চূড়ান্তকরণ না বলা হলেও ঘাম নয়।
foo বিন্যাস

2

বৈশ্বিক / স্থিতিশীল জায়গায় (প্রয়োজনের বাইরে) যুক্ত করা জিনিসগুলি সরিয়ে ফেলা সহজ হতে পারে এবং যখন অবজেক্টটি সরানো হয় তখন তা সরানো দরকার। এই ক্ষেত্রে:

    প্রাইভেট শূন্যতা যোগ
        দুর্বলAwtEventListener = নতুন WeakAWTEventListener (এটি);

        Toolkit.getDefaultToolkit ()। AddAWTEventListener (দুর্বলAwtEventListener, AWTEvent.MOUSE_EVENT_MASK);
    }

    @অগ্রাহ্য করা
    সুরক্ষিত অকার্যকর চূড়ান্তকরণ () নিক্ষেপযোগ্য {
        super.finalize ();

        যদি (দুর্বলআউটভেন্টলিস্টনার! = নাল) {
            । Toolkit.getDefaultToolkit () removeAWTEventListener (weakAwtEventListener);
        }
    }

এটির জন্য অতিরিক্ত প্রচেষ্টা দরকার, কারণ শ্রোতার যখন thisকনস্ট্রাক্টরের কাছে দেওয়া দৃষ্টান্তটির finalize()দৃ reference় উল্লেখ রয়েছে তখন সেই দৃষ্টান্তটি কখনও পৌঁছনীয় হবে না, সুতরাং এটি কখনই পরিষ্কার হবে না। অন্যদিকে, শ্রোতা যদি সেই বস্তুর প্রতি দুর্বল রেফারেন্স ধরে রাখেন, যেমন নামটি সূত্রে বোঝা যায়, এটি তৈরি না করা উচিত যখন এমন সময়ে পরিষ্কার হয়ে যায়। বস্তুটির জীবনচক্র অ্যাপ্লিকেশন শব্দার্থক প্রয়োগের জন্য সঠিক সরঞ্জাম নয় the
হলগার

0

আইরিচ - আপনি ব্যয়বহুল সংস্থাগুলির জন্য পুলিং ব্যবস্থা বাস্তবায়নের মাধ্যম হিসাবে চূড়ান্তকরণ পদ্ধতিটি ব্যবহার করতে পারেন - যাতে তারা জিসিরও পায় না।


0

পার্শ্ব নোট হিসাবে:

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

উত্স: চূড়ান্তকরণ () জাভা -9 এ অবমূল্যায়িত


0

সম্পদগুলি (ফাইল, সকেট, স্ট্রিম ইত্যাদি) একবার বন্ধ করার প্রয়োজন যখন আমরা সেগুলি শেষ করি। তাদের সাধারণত close()পদ্ধতি থাকে যা আমরা সাধারণত বিবৃতি finallyবিভাগে কল করি try-catch। কখনও কখনওfinalize() কয়েকজন বিকাশকারীও ব্যবহার করতে পারেন তবে আইএমও এটি উপযুক্ত উপায় নয় কারণ চূড়ান্তকরণকে সর্বদা ডাকা হবে বলে কোনও গ্যারান্টি নেই।

জাভা 7-এ আমরা চেষ্টা করেছি -সংস্থানসমূহের বিবৃতি যা ব্যবহার করা যেতে পারে:

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
  // Processing and other logic here.
} catch (Exception e) {
  // log exception
} finally {
  // Just in case we need to do some stuff here.
}

উপরোক্ত উদাহরণে চেষ্টা-সহ-সংস্থানটি স্বয়ংক্রিয়ভাবে পদ্ধতিটি BufferedReaderআহ্বানের মাধ্যমে সংস্থানটি বন্ধ করে দেবে close()। আমরা চাইলে আমরা ক্লাসেবলকে আমাদের নিজস্ব ক্লাসেও প্রয়োগ করতে পারি এবং এটি একইভাবে ব্যবহার করতে পারি। আইএমও এটি বোঝা আরও পরিষ্কার এবং সহজ বলে মনে হচ্ছে।


0

ব্যক্তিগতভাবে, আমি finalize()এক বিরল পরিস্থিতিতে ব্যতীত প্রায় কখনও ব্যবহার করি না : আমি একটি কাস্টম জেনেরিক ধরণের সংগ্রহ তৈরি করেছি এবং আমি একটি কাস্টম finalize()পদ্ধতি লিখেছি যা নিম্নলিখিতগুলি করে:

public void finalize() throws Throwable {
    super.finalize();
    if (destructiveFinalize) {
        T item;
        for (int i = 0, l = length(); i < l; i++) {
            item = get(i);
            if (item == null) {
                continue;
            }
            if (item instanceof Window) {
                ((Window) get(i)).dispose();
            }
            if (item instanceof CompleteObject) {
                ((CompleteObject) get(i)).finalize();
            }
            set(i, null);
        }
    }
}

( CompleteObjectএকটি ইন্টারফেস আপনাকে তা নির্দিষ্ট আপনি খুব কমই প্রয়োগ বাস্তবায়িত করেছি যে দেয় যে আমি তৈরি Objectপদ্ধতি মত #finalize(), #hashCode()এবং #clone())

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


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

0

গৃহীত উত্তরের তালিকায় চূড়ান্ত করার সময় কোনও সংস্থান বন্ধ করা যায়।

তবে এই উত্তরটি দেখায় যে কমপক্ষে জেআই 8 জেআইটি সংকলক সহ, আপনি অপ্রত্যাশিত সমস্যাগুলিতে চলে যান যেখানে কখনও কখনও ফাইনালাইজারটি বলা হয় আপনি নিজের অবজেক্টের দ্বারা বজায় রাখা স্ট্রিম থেকে পড়া শেষ করার আগেই।

এমনকি সেই পরিস্থিতিতে কলিং চূড়ান্ত করার পরামর্শ দেওয়া হবে না


এটি কাজ করবে, যদি অপারেশনটি থ্রেডটিকে নিরাপদ করা হয় তবে এটি আবশ্যক, কারণ চূড়ান্তকরণকারীকে নির্বিচারে থ্রেড দ্বারা ডাকা যেতে পারে। যেহেতু সঠিকভাবে প্রয়োগ করা থ্রেড সুরক্ষা থেকেই বোঝা যায় যে কেবল ঘনিষ্ঠ অপারেশনই নয়, তবে সংস্থানটি ব্যবহার করে ক্রিয়াকলাপগুলি একই বস্তু বা লকটির সাথে সমলয় করতে হবে, ব্যবহার এবং ঘনিষ্ঠ অপারেশনের মধ্যে একটি ঘটনা ঘটে যাওয়ার আগেই ঘটে যা খুব তাড়াতাড়ি বাধা দেয় which চূড়ান্ত। তবে, অবশ্যই, পুরো ব্যবহারের জন্য একটি উচ্চ মূল্যে ...
হোলার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.