জাভা থ্রেড আবর্জনা সংগ্রহ করা হয়েছে কি না


85

এই প্রশ্নটি কোনও সাইটে পোস্ট করা হয়েছিল। আমি সেখানে সঠিক উত্তর খুঁজে পাইনি, তাই আমি এখানে এটি আবার পোস্ট করছি।

public class TestThread {
    public static void main(String[] s) {
        // anonymous class extends Thread
        Thread t = new Thread() {
            public void run() {
                // infinite loop
                while (true) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                    // as long as this line printed out, you know it is alive.
                    System.out.println("thread is running...");
                }
            }
        };
        t.start(); // Line A
        t = null; // Line B
        // no more references for Thread t
        // another infinite loop
        while (true) {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
            }
            System.gc();
            System.out.println("Executed System.gc()");
        } // The program will run forever until you use ^C to stop it
    }
}

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

আশা করি কোড এবং প্রশ্ন উভয়ই এবার পরিষ্কার হয়ে গেছে।

উত্তর:


124

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

এটি বিবেচনা করুন, কেন আপনার মূল থ্রেডটি আবর্জনা সংগ্রহ করা হচ্ছে না, কেউই সেটিকে উল্লেখ করছে না।


17
এই উত্তরটি যেমন বর্তমানে দাঁড়িয়েছে, প্রশ্ন উত্থাপন করে যদি থ্রেডগুলি একেবারে GC'ed করা যায় (তারা শেষ করার পরে)। যেহেতু এই প্রশ্নের সদৃশ হিসাবে চিহ্নিত করা হয় এই এক , এটা উল্লেখ করা উচিত যে থ্রেড আর হিসাবে "গার্বেজ কালেকশন শিকড়" হিসাবে চিহ্নিত করা হবে পরে তারা বিনষ্ট, এবং এইভাবে তারা জিসি জন্য পৌঁছানো হয়ে।
bluenote10

13
শেষ বাক্যটি অনুপ্রবেশকারী: "কেন আপনার মূল সুতোটি আবর্জনা হয়ে উঠছে না ..."।
নির্ধারিত

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

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

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

23

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

তবে আপনি একটি থ্রেডকে "ডেমন" থ্রেড তৈরি করতে পারেন (দেখুন Thread.setDaemon(boolean))। ডেমন থ্রেডটি নন-ডেমন থ্রেডের চেয়ে বেশি আবর্জনা সংগ্রহ করা হয় না, তবে চলমান সমস্ত থ্রেড ডিমন হিসাবে জেভিএম প্রস্থান করে। এটি কল্পনা করার একটি উপায় হ'ল প্রতিটি থ্রেড, যখন এটি শেষ হয়, পরীক্ষা করে যে কিছু অ-ডেমন চলমান থ্রেড রয়েছে কিনা; যদি তা না হয় তবে সমাপ্তি থ্রেড একটি System.exit()কল জোর করে , যা জেভিএম থেকে বেরিয়ে আসে (চলমান ডিমন থ্রেডগুলি মেরে ফেলে)। এটি কোনও জিসি সম্পর্কিত সমস্যা নয়; একরকমভাবে, থ্রেডগুলি ম্যানুয়ালি বরাদ্দ করা হয়। যাইহোক, এইভাবে JVM আধা-দুর্বৃত্ত থ্রেড সহ্য করতে পারে। এটি সাধারণত Timerউদাহরণগুলির জন্য ব্যবহৃত হয় ।


19

জেভিএমের সমস্ত চলমান থ্রেডের একটি উল্লেখ রয়েছে।

কোনও থ্রেড (বা এটি নির্দেশিত জিনিসগুলি) আবর্জনা-সংগ্রহ করা হবে যখন এটি এখনও চলছে।


13

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

থ্রেডটি তৈরি করা হলে এটি বর্তমান থ্রেড গ্রুপে যুক্ত করা হয়। আপনি বর্তমান থ্রেড গ্রুপে থ্রেডগুলির একটি তালিকা পেতে পারেন, সুতরাং এটির একটি রেফারেন্স পাওয়ার অন্য উপায়।

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