জাভা জন্য কোন ডেস্ট্রাক্টর আছে?


594

জাভা জন্য কোন ডেস্ট্রাক্টর আছে? আমি এ সম্পর্কে কোনও ডকুমেন্টেশন খুঁজে পেতে সক্ষম হবে বলে মনে হচ্ছে না। যদি তা না থাকে তবে আমি কীভাবে একই প্রভাব অর্জন করতে পারি?

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

সাধারণত একটি সি / সি ++ প্রোগ্রামার হওয়ায় আমি ভেবেছিলাম এটি বাস্তবায়নের জন্য ক্ষুদ্র হবে। (এবং তাই আমি এটি শেষ পর্যন্ত বাস্তবায়নের পরিকল্পনা করেছি।) আমি আমার প্রোগ্রামটি এমনভাবে তৈরি করেছি যাতে সমস্ত 'রিসেট-সক্ষম' অবজেক্ট একই শ্রেণিতে থাকবে যাতে একটি রিসেট বোতাম চাপলে আমি কেবল সমস্ত 'লাইভ' অবজেক্টগুলিকে ধ্বংস করতে পারি।

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


7
আপনার প্রয়োজন নেই এমন অবজেক্টের রেফারেন্স রাখলে কেবল একটি মেমরি ফাঁস হয়। যেমন আপনার প্রোগ্রামে একটি বাগ আছে। জিসি এটি প্রয়োজন অনুসারে চালিত হবে (কখনও কখনও তাড়াতাড়ি)
পিটার লরে

17
আপনি যদি বস্তুর মাধ্যমে ডেটা দ্রুত প্রক্রিয়াকরণ করতে থাকেন তবে ভার্চুয়াল মেশিনটি শীঘ্রই পর্যাপ্ত পরিমাণে জিসি চালাবে না। জিসি সর্বদা বজায় রাখতে পারে বা সঠিক সিদ্ধান্ত নিতে পারে এমন ধারণাটি একটি মিথ্যাচার।
কিভেলি

1
@ কিভেলি কি ত্রুটি দেওয়ার আগে জেভিএম জিসি চালাবেন না?
WVrock

4
হ্যাঁ, জাভার জন্য যদি এমন কোনও ডেস্ট্রাক্টর থাকত যে এটি একেবারে ধ্বংস করে দেয় it
টোমা জ্যাটো - মনিকা

উত্তর:


526

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

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

একটি প্রশ্ন ছিল যা সম্প্রতি চূড়ান্ত করার গভীরতার আলোচনা তৈরি করেছে, যাতে প্রয়োজনে আরও গভীরতা প্রদান করা উচিত ...


5
এই প্রসঙ্গে "বন্ধ ()" কি জাভা.এলং.আউটোক্লোজেবলের পদ্ধতিটিকে বোঝায়?
শ্রীধর সারনোবাত

21
না, অটোক্লোজেবল জাভা 7-তে প্রবর্তিত হয়েছিল তবে 'ক্লোজ ()' কনভেনশনটি প্রায় দীর্ঘকাল ধরে চলেছে।
জন অনস্টট

আপনি কেন ভবিষ্যদ্বাণী করতে পারবেন না কখন (বা এমনকি) কোনও জিনিস ধ্বংস হয়ে যাবে। ভবিষ্যদ্বাণী করার অন্যান্য উপায় কী?
dctremblay

@dctremblay অবজেক্ট ধ্বংসটি আবর্জনা সংগ্রহকারী দ্বারা সম্পন্ন করা হয় এবং আবর্জনা সংগ্রহকারী প্রয়োগের সময়কালে কখনও চলতে পারে না।
পিরো বলেছেন মোনিকা

4
লক্ষ্য করুন finalizeপদ্ধতি অবচিত হয়েছে জাভা 9. মধ্যে
Lii

124

কটাক্ষপাত আছে চেষ্টা-সঙ্গে-সম্পদ বিবৃতি। উদাহরণ স্বরূপ:

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
  System.out.println(br.readLine());
} catch (Exception e) {
  ...
} finally {
  ...
}

এখানে যে সংস্থানটির আর প্রয়োজন নেই সেগুলি BufferedReader.close()পদ্ধতিতে মুক্ত করা হয় । আপনি নিজের শ্রেণি তৈরি করতে পারেন যা প্রয়োগ করে AutoCloseableএবং একই ধরণের ব্যবহার করে।

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


12
আমি আশ্চর্য হয়েছি যে এর এত কম ভোট রয়েছে। এটা আসল উত্তর।
নুরেটিন

20
আমি প্রকৃত উত্তর যে দ্বিমত। যদি কোনও উদাহরণের কোনও সংস্থান থাকে তবে এটি একাধিক পদ্ধতি কলগুলিতে বৃহত্তর সময়ের মধ্যে পরিচালনা করে, তারপরে-সংস্থানগুলি সাহায্য করবে না। রেট রিসোর্সটি বন্ধ করে আবার খুলতে না পারলে বলা হয় যে পদ্ধতিগুলি ডাকা হবে - এটি সাধারণ ঘটনা নয়।
এরিক

14
বস্তুত, এই হল না প্রকৃত উত্তর। কোনও অবজেক্টের বিন্যাস পরিচালনা করতে এই কাঠামোটি ব্যবহার করা অসম্ভব, যদি না অবজেক্টের নির্মাণ ও ব্যবহার সম্পূর্ণরূপে ই-কেপুলেটেড না করে tryএবং finallyকোনও কলকে বাধ্য করার জন্য ব্যবহার না করা হয় obj.finalize()। এমনকি এই সেটআপটিও ওপি-র দ্বারা উত্থিত সমস্যার সমাধান করতে পারে না: "রিসেট" বোতামের সাহায্যে অবজেক্ট ড্যামেজ মিড-প্রোগ্রামটি ট্রিগার করা।
7yl4r

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

1
@ নুরেটিন জাভা 7 কেবল 3 মাসের জন্য বাইরে ছিল যখন প্রশ্ন জিজ্ঞাসা করা হয়েছিল, এটি যদি এটি আরও বুঝতে সহায়তা করে।
করসিকা

110

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

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

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


4
নেটিভ রিসোর্স উল্লেখ করার জন্য আপনাকে ধন্যবাদ - এটি এমন একটি ক্ষেত্র যেখানে "ডেস্ট্রাক্টরের মতো" পদ্ধতিটি কার্যকর।
নাথান ওসমান

হ্যাঁ, সি ++ এ দেশীয় কলের মাধ্যমে বরাদ্দকৃত সংস্থানগুলি / হ্যান্ডলগুলি মুক্ত করে এখনই আমি একই সমস্যার মুখোমুখি।
নিক্ক

@ ডিডিমিট্রভ, তত্ত্বগতভাবে জাভা সুস্পষ্ট অবনতি বাস্তবায়ন করতে পারে? নাকি এটি যৌক্তিক দ্বন্দ্ব?
মিলস

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

31

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

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

Resource r = new Resource();
try {
    //work
} finally {
    r.dispose();
}

নিষ্পত্তিযোগ্য অবজেক্টটি ব্যবহারের চেষ্টাগুলি একটি রানটাইম ব্যতিক্রম ছুঁড়ে ফেলা উচিত ( IllegalStateException দেখুন )।


সম্পাদনা করুন:

আমি ভাবছিলাম, যদি আমি কেবল সমস্ত কিছু ডেটা অবলম্বন করতে এবং আবর্জনা সংগ্রহকারী তাদের সংগ্রহের জন্য অপেক্ষা করতে থাকি, যদি আমার ব্যবহারকারী বারবার ডেটা প্রবেশ করে রিসেট বোতাম টিপায় তবে কি কোনও স্মৃতি ফাঁস হবে না?

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


1
এটাই ডেরিফারেন্স মানে না। এটি "কোনও অবজেক্টের সর্বশেষ রেফারেন্সটি নালায় সেট করে না" বরং এটি একটি রেফারেন্সের থেকে মূল্য পাওয়া (পড়া) করা হয় যাতে আপনি এটি পরবর্তী ক্রিয়াকলাপের জন্য ব্যবহার করতে পারেন।

1
চেষ্টা করুন..আপনি এখনও একটি বৈধ এবং প্রস্তাবিত পদ্ধতির? মনে করুন, আমি আগে চূড়ান্তকরণের জন্য একটি দেশীয় পদ্ধতি কল করছিলাম (), আমি কি শেষ অবধি কলটি স্থানান্তর করতে পারি? class Resource { finalize() { destroy(); } protected native void destroy(); } class Alt_Resource { try (Resource r = new Resource()) { // use r } finalize { r.destroy(); }
আশিমা

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

21

জাভা 1.7 প্রকাশিত হওয়ায় আপনার কাছে এখন try-with-resourcesব্লকটি ব্যবহারের অতিরিক্ত বিকল্প রয়েছে । উদাহরণ স্বরূপ,

public class Closeable implements AutoCloseable {
    @Override
    public void close() {
        System.out.println("closing..."); 
    }
    public static void main(String[] args) {
        try (Closeable c = new Closeable()) {
            System.out.println("trying..."); 
            throw new Exception("throwing..."); 
        }
        catch (Exception e) {
            System.out.println("catching..."); 
        }
        finally {
            System.out.println("finalizing..."); 
        } 
    }
}

আপনি যদি এই ক্লাসটি c.close()কার্যকর করেন তবে tryব্লকটি যখন ছেড়ে যায় তখন এবং কার্যকর করা হবে catchএবং finallyব্লকগুলি কার্যকর করার আগে । finalize()পদ্ধতির ক্ষেত্রে অসদৃশ , close()কার্যকর করার গ্যারান্টিযুক্ত। যাইহোক, ধারাটিতে এটি স্পষ্টভাবে কার্যকর করার দরকার নেই finally


আমরা যদি চেষ্টা-সহ-সংস্থানগুলি ব্যবহার না করি? আমি মনে করি আমরা কেবল ক্লোজকে চূড়ান্তভাবে কল করতে পারি () কেবল এটি নিশ্চিত করার জন্য যে নিকটে ডাকা হয়েছে।
shintoZ

3
@ শিন্টোজেড আমি উপরের উত্তরগুলিতে যেমন পড়লাম তেমন finalize()মৃত্যুদণ্ডের নিশ্চয়তা নেই
আসিফ মোশতাক

14

চূড়ান্তকরণের বাস্তবায়নের উপর নির্ভর না করার জন্য আমি অন্যান্য উত্তরে সম্পূর্ণরূপে একমত।

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

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

এই সুবিধা বিনির্মাণ আচরণ হচ্ছে না ঢিলেঢালাভাবে মিলিত আপনার প্রোগ্রাম বাকি থেকে।


অ্যাডশুটডাউনহুক স্পষ্টতই জাভা ১.৩ এ চালু হয়েছিল। যাইহোক, এটি আমার কাছে 1.5। : :) এই দেখুন stackoverflow.com/questions/727151/...
skiphoppy

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

11

না, java.lang.Object#finalizeআপনি পেতে পারেন নিকটতম।

যাইহোক, কখন (এবং যদি) এটি ডাকা হয়, গ্যারান্টিযুক্ত হয় না।
দেখা:java.lang.Runtime#runFinalizersOnExit(boolean)


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

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

7

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

Java.lang.ref.PantomReferences ব্যবহার করে কোনও জিনিস ধ্বংস হয়ে যাওয়ার পরে আপনাকে অবহিত করা যেতে পারে (প্রকৃতপক্ষে, এটি ধ্বংস হয়েছে বলে কিছুটা ভুল হতে পারে, তবে যদি এর কোনও ফ্যান্টম রেফারেন্সটি সারি করা থাকে তবে এটি আর পুনরুদ্ধারযোগ্য নয়, যা সাধারণত পরিমাণ মতো একই জিনিস). একটি সাধারণ ব্যবহার হ'ল:

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

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


উইক রেফারেন্সের পরিবর্তে ফ্যান্টম রেফারেন্স কেন?
uckelman

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

ফ্যান্টম রেফারেন্সে ইঙ্গিত দেওয়ার জন্য আপনাকে ধন্যবাদ। এটি নিখুঁত নয়, তবে তবুও ভাল কিছু নয়।
foo

@ স্টিভ জেসোপ কী অনুমান রেফারেন্সের তুলনায় দুর্বল রেফারেন্স বলে মনে করেন?
হলগার

6

finalize()ফাংশন বিনাশকারী হয়।

তবে এটি সাধারণত ব্যবহার করা উচিত নয় কারণ এটি জিসির পরে আহ্বান করা হয়েছিল এবং কখন তা ঘটবে তা আপনি বলতে পারবেন না (যদি কখনও হয়)।

তদ্ব্যতীত, যে জিনিসগুলি রয়েছে তা বাতিল করতে একাধিক জিসি লাগবে finalize()

try{...} finally{...}বিবৃতি ব্যবহার করে আপনার কোডটিতে লজিক্যাল জায়গাগুলি পরিষ্কার করার চেষ্টা করা উচিত !


5

আমি বেশিরভাগ উত্তরের সাথে একমত

আপনি উভয় finalizeবা সম্পূর্ণরূপে নির্ভর করবে নাShutdownHook

পাকা করা

  1. JVM গ্যারান্টি দেয় না কখন এই finalize()পদ্ধতিটি চালু করা হবে।

  2. finalize()কেবল একবার জিসি থ্রেড দ্বারা কল হয়। যদি কোনও বিষয় চূড়ান্তকরণ পদ্ধতি থেকে নিজেকে পুনরুদ্ধার করে, তবে finalizeতাকে আর কল করা হবে না।

  3. আপনার অ্যাপ্লিকেশনটিতে আপনার কিছু লাইভ অবজেক্ট থাকতে পারে, যার উপর আবর্জনা সংগ্রহ কখনই চাওয়া হয় না।

  4. কোন Exceptionযে চূড়ান্ত হচ্ছে পদ্ধতি দ্বারা নিক্ষিপ্ত হয় জিসি থ্রেড দ্বারা উপেক্ষা করা হয়

  5. System.runFinalization(true)এবং Runtime.getRuntime().runFinalization(true)পদ্ধতিগুলি আহ্বান করার finalize()পদ্ধতির সম্ভাবনা বাড়িয়ে তোলে তবে এখন এই দুটি পদ্ধতি হ্রাস করা হয়েছে। থ্রেড সুরক্ষার অভাব এবং সম্ভাব্য অচলাবস্থা তৈরির কারণে এই পদ্ধতিগুলি খুব বিপজ্জনক।

shutdownHooks

public void addShutdownHook(Thread hook)

একটি নতুন ভার্চুয়াল-মেশিন শাটডাউন হুক নিবন্ধন করে।

জাভা ভার্চুয়াল মেশিন দুটি ধরণের ইভেন্টের প্রতিক্রিয়া হিসাবে বন্ধ করে দেয়:

  1. প্রোগ্রামটি সাধারণত প্রস্থান করে, যখন সর্বশেষ নন-ডেমন থ্রেডটি প্রস্থান হয় বা প্রস্থান (সমতুল্য System.exit) পদ্ধতিটি চালু করা হয়, বা
  2. ভার্চুয়াল মেশিনটি কোনও ব্যবহারকারীর বাধাদানের প্রতিক্রিয়া হিসাবে সমাপ্ত হয় যেমন ^ C টাইপ করে বা সিস্টেম-ব্যাপী ইভেন্ট, যেমন ব্যবহারকারী লগঅফ বা সিস্টেম শাটডাউন।
  3. একটি শাটডাউন হুক কেবল একটি প্রাথমিক কিন্তু অ-শুরু থ্রেড। ভার্চুয়াল মেশিনটি যখন শাটডাউন ক্রমটি শুরু করবে এটি কিছু অনির্দিষ্ট ক্রমে সমস্ত নিবন্ধিত শাটডাউন হুক শুরু করবে এবং তাদের একযোগে চলতে দেবে। সমস্ত হুকস শেষ হয়ে গেলে এটি চূড়ান্তকরণ-অন-প্রস্থান সক্ষম করা থাকলে সমস্ত অনিবন্ধিত চূড়ান্তকারীগুলি চালিত হবে।
  4. অবশেষে, ভার্চুয়াল মেশিনটি বন্ধ হয়ে যাবে। নোট করুন যে ডেমন থ্রেডগুলি শাটডাউন ক্রম চলাকালীন চলতে থাকবে, যেমন প্রস্থান পদ্ধতিতে অনুরোধ করে শাটডাউন শুরু করা হলে নন-ডেমন থ্রেডগুলিও চলবে।
  5. শাটডাউন হুকগুলিও তাদের কাজ দ্রুত শেষ করা উচিত। যখন কোনও প্রোগ্রাম প্রস্থানটি প্রত্যাশা করে তখন হ'ল ভার্চুয়াল মেশিনটি তাত্ক্ষণিকভাবে বন্ধ হয়ে প্রস্থান করবে।

    এমনকি ওরাকল ডকুমেন্টেশনও এটি উদ্ধৃত করেছে

বিরল পরিস্থিতিতে ভার্চুয়াল মেশিনটি বাতিল হতে পারে, অর্থাৎ, পরিষ্কারভাবে বন্ধ না করে চালানো বন্ধ করুন

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

উপসংহার : ব্লকগুলি যথাযথভাবে ব্যবহার করুন try{} catch{} finally{}এবং finally(}ব্লকটিতে গুরুত্বপূর্ণ সংস্থানগুলি ছেড়ে দিন । finally{}ব্লকে রিসোর্স মুক্তির সময় , ধরা Exceptionএবং Throwable


4

যদি এটি কেবল স্মৃতি থাকে তবে আপনি উদ্বিগ্ন হন না। কেবলমাত্র জিসিকে বিশ্বাস করুন এটি একটি ভাল কাজ করে job আমি আসলে এটি সম্পর্কে দক্ষতার সাথে এমন কিছু দেখেছি যা কিছু পরিস্থিতিতে বড় অ্যারে ব্যবহার করার চেয়ে ক্ষুদ্র বস্তুগুলির গাদা তৈরি করা পারফরম্যান্সের পক্ষে আরও ভাল।


3

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


1
এটি সঠিক উত্তর যখন প্রশ্নে সংস্থানটিতে কোনও একক মালিক থাকে এবং এর সাথে অন্য কোড দ্বারা "চুরি" করা যায় তার কোনও উল্লেখ থাকে না।
স্টিভ জেসপ

3

লম্বোকে একটি @ ক্লিনআপ টিকা আছে যা বেশিরভাগই সি ++ ধ্বংসকারীদের মতো দেখা যায়:

@Cleanup
ResourceClass resource = new ResourceClass();

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

@Cleanup("dispose")
ResourceClass resource = new ResourceClass();

2
আমি যে সুবিধাটি দেখছি তা হল কম বাসা বাঁধবে (যা আপনার কাছে "ধ্বংসাত্মক" প্রয়োজন এমন অনেকগুলি অবজেক্ট থাকলে তা উল্লেখযোগ্য হতে পারে)।
অ্যালেক্সি

রিসোর্স ব্লকটিতে একটি শটে একাধিক সংস্থান থাকতে পারে
আলেকজান্ডার - পুনরায় স্থাপন করুন মনিকা

1
তবে এর মধ্যে তাদের মধ্যে নির্দেশনা থাকতে পারে না।
আলেক্সি

ফেয়ার। আমি মনে করি তখন সেই প্রস্তাবটি হ'ল চেষ্টা করুন-সংস্থান-রিসোর্সকে, এমনকি একাধিক সংস্থার জন্যও, যদি না তাদের মধ্যে এমন কোনও নির্দেশের প্রয়োজন হয় যা আপনাকে রিসোর্স ব্লক (বাড়তি বাসা বাঁধাই) করতে নতুন চেষ্টা করতে বাধ্য করে, তবে ব্যবহার করুন@Cleanup
আলেকজান্ডার - রিইনস্টেট মনিকা

2

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


2

এখানে অনেক দুর্দান্ত উত্তর, তবে কেন আপনাকে চূড়ান্তকরণ () ব্যবহার করা এড়ানো উচিত সে সম্পর্কে কিছু অতিরিক্ত তথ্য রয়েছে

যদি জেভিএম System.exit()বা তার কারণে প্রস্থান করে তবে Runtime.getRuntime().exit()ফাইনালাইজারগুলি ডিফল্টরূপে চালিত হবে না। জাভাডোক থেকে রানটাইম.এক্সিটের জন্য () :

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

তুমি কল করতে পার System.runFinalization() তবে এটি কেবল "সমস্ত বকেয়া চূড়ান্তকরণ সম্পূর্ণ করার জন্য সেরা প্রচেষ্টা" করে তোলে - গ্যারান্টি নয়।

একটি System.runFinalizersOnExit()পদ্ধতি আছে, তবে এটি ব্যবহার করবেন না - এটি অনিরাপদ, অনেক আগেই হ্রাস পেয়েছে।


1

আপনি যদি জাভা অ্যাপলেট লিখছেন তবে আপনি অ্যাপলেট "ধ্বংস ()" পদ্ধতিটি ওভাররাইড করতে পারেন। এটাই...

 * Called by the browser or applet viewer to inform
 * this applet that it is being reclaimed and that it should destroy
 * any resources that it has allocated. The stop() method
 * will always be called before destroy().

অবশ্যই আপনি যা চান তা নয় , তবে অন্য লোকেরা যা খুঁজছেন তা হতে পারে।


1

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

... ওপি আসলে যা চায় তা করার একটি দুর্দান্ত সুস্পষ্ট সমাধান হতে পারে না যা আপনার সমস্ত অবজেক্টগুলিকে একটি "প্লেপেন" সাজানোর জন্য পুনরায় সেট করতে হবে, যেখানে অন্য সমস্ত পুনঃস্থাপনযোগ্য বস্তুগুলি কেবল কোনও ধরণের মাধ্যমে রেফারেন্স করতে পারে অ্যাক্সেসর অবজেক্টের ...

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

এর মধ্যে যদি কোনও অবজেক্ট থাকে Closeable(বা না হয় তবে একটি closeপদ্ধতি থাকে) আপনি Bagতৈরি হওয়ার সাথে সাথে এগুলি প্লেপেইনে রেখে দিতে পারেন (এবং সম্ভবত খোলা হয়েছে), এবং প্লেপেন কেটে দেওয়ার আগে অ্যাকসেসরের শেষ কাজটি হবে সব Closeablesবন্ধ করে দিয়ে ...?

কোডটি সম্ভবত এরকম কিছু দেখাচ্ছে:

accessor.getPlaypen().closeCloseables();
accessor.setPlaypen( new Playpen() );

closeCloseablesসম্ভবত জাভাএফএক্স থ্রেডে কোনও নির্দিষ্ট / যে কোনও থ্রেডে যথাযথভাবে সমাপ্ত হওয়া উচিত CountdownLatch(যেমন উপযুক্ত হিসাবে অপেক্ষা করতে হবে) সম্পর্কিত কোনও ল্যাচ (উদাহরণস্বরূপ ) জড়িত সম্ভবত একটি ব্লকিং পদ্ধতি হবে।RunnablesCallablesPlaypen


0

যদিও জাভার জিসি প্রযুক্তিতে যথেষ্ট অগ্রগতি হয়েছে, তবুও আপনাকে আপনার উল্লেখগুলি মনে রাখতে হবে mind আপাতদৃষ্টিতে তুচ্ছ রেফারেন্স নিদর্শনগুলির অনেকগুলি ঘটনা যা হুডের নীচে ইঁদুরের বাসা হয়।

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


0

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

চূড়ান্ত ()

একটি প্রশ্ন ছিল যা চূড়ান্ত করার গভীরতার আলোচনা তৈরি করেছে , যাতে প্রয়োজনে আপনার আরও গভীরতা পাওয়া উচিত ...


0

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


-3

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

উদাহরণ:

public myDestructor() {

variableA = 0; //INT
variableB = 0.0; //DOUBLE & FLOAT
variableC = "NO NAME ENTERED"; //TEXT & STRING
variableD = false; //BOOL

}

আদর্শভাবে এটি সমস্ত পরিস্থিতিতে কাজ করবে না, তবে যেখানে বিশ্বব্যাপী ভেরিয়েবল রয়েছে এটি ততক্ষণ কাজ করবে যতক্ষণ না আপনার একটি টন নেই।

আমি জানি আমি সেরা জাভা প্রোগ্রামার নই, তবে মনে হয় এটি আমার পক্ষে কাজ করছে।


অপরিবর্তনীয় বস্তুগুলিকে আরও ব্যবহার করার চেষ্টা করুন, আপনি 'পাওয়ার' পরে এটি আরও বেশি
অর্থবোধ

5
এটি এতটা ভুল নয় কারণ এটি অর্থহীন - অর্থাত্ কিছুই অর্জন করে না। আপনার প্রোগ্রামটি যদি সঠিকভাবে কাজ করার জন্য কাঁচা ধরণের পুনরায় সেট করা প্রয়োজন, তবে আপনার ক্লাসের উদাহরণগুলি ভুলভাবে স্কোপ করা হয়েছে, যার অর্থ আপনি সম্ভবত কোনও নতুন অবজেক্ট () তৈরি না করেই কোনও বিদ্যমান অবজেক্টের বৈশিষ্ট্যগুলিকে একটি নতুন অবজেক্টের বৈশিষ্ট্যে পুনরায় সাইন করছেন।
simo.3792

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