কীভাবে জাভা প্রক্রিয়াটি গ্রেপ্তারভাবে বন্ধ করবেন?


88

লিনাক্স এবং উইন্ডোজগুলিতে আমি কীভাবে কোনও জাভা প্রক্রিয়া বন্ধ করব?

কখন Runtime.getRuntime().addShutdownHookডাকা হবে, এবং কখন হবে না?

চূড়ান্তকারীদের সম্পর্কে কী, তারা এখানে সহায়তা করে?

আমি কোনও শেল থেকে জাভা প্রক্রিয়াতে কোনও ধরণের সংকেত পাঠাতে পারি?

আমি অগ্রাধিকারযোগ্য পোর্টেবল সমাধানগুলির সন্ধান করছি।


আপনি কি করুণভাবে বলতে চেয়েছেন তা সত্যই নির্ধারণ করা উচিত। (দয়া করে)
হেনরি বি

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

উত্তর:


82

ভিএম জোর করে হত্যা করা হয়নি এমন সমস্ত ক্ষেত্রে শাটডাউন হুকগুলি কার্যকর করা হয়। সুতরাং, যদি আপনি "স্ট্যান্ডার্ড" কিল ( SIGTERMএকটি কিল কমান্ড থেকে) জারি করতে থাকেন তবে তারা কার্যকর করবে। একইভাবে, তারা কল করার পরে কার্যকর করা হবে System.exit(int)

তবে একটি হার্ড কিল ( kill -9বা kill -SIGKILL) তারপরে তারা কার্যকর করবে না। একইভাবে (এবং স্পষ্টতই) তারা যদি কম্পিউটার থেকে শক্তি টানেন, এটিকে ফুটন্ত লাভার একটি ভ্যাটে ফেলে রাখবেন বা সিপিইউকে কোনও স্লেজহ্যামার দিয়ে টুকরো টুকরো করে ফেলবেন তবে তারা কার্যকর করবে না। যদিও আপনি সম্ভবত এটি ইতিমধ্যে জানতেন।

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


4
দুর্ভাগ্যক্রমে, এটি উইন্ডোজ 7 (64 বিট) এ কাজ করবে বলে মনে হচ্ছে না। আমি ফোর্স পতাকা ছাড়াই টাস্কিল ব্যবহার করার চেষ্টা করেছি এবং নিম্নলিখিত ত্রুটির মুখোমুখি হয়েছি: "ত্রুটি: পিআইডি 14324 সহ প্রক্রিয়াটি শেষ করা যায়নি ason কারণ: এই প্রক্রিয়াটি কেবল জোর করে (এফ / বিকল্পের সাহায্যে) বন্ধ করা যায়।" "/ F" বল প্রয়োগের বিকল্প সরবরাহ করা অবশ্যই তাত্ক্ষণিকভাবে প্রক্রিয়াটি বন্ধ করে দেবে।
জেসন হান্টলি

আপনি চূড়ান্তকারীদের চালিত হওয়ার উপর নির্ভর করতে পারবেন না।
থরবজর্ন রাভন অ্যান্ডারসন

47

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

সরলীকৃত কোডটি এখানে:

নিয়ন্ত্রিত অ্যাপ্লিকেশন:
এটি
ফলোভিং ভিএম প্যারামিটারগুলি দিয়ে চালান: -ডকম.সুন.ম্যানেজমেন্ট.জেএমএক্স্রমেট
-ডকম.সুন.ম্যানেজমেন্ট.জএমএক্স্রমেট.পোর্ট = 9999
-ডকম.সুন.ম্যানেজমেন্ট.জমেক্স্রেমোট.অটেক্সটেট = ভুয়া
-ডকম.সুন.ম্যানেজমেন্ট। jmxremote.ssl = মিথ্যা

//ThreadMonitorMBean.java
public interface ThreadMonitorMBean
{
String getName();
void start();
void stop();
boolean isRunning();
}

// ThreadMonitor.java
public class ThreadMonitor implements ThreadMonitorMBean
{
private Thread m_thrd = null;

public ThreadMonitor(Thread thrd)
{
    m_thrd = thrd;
}

@Override
public String getName()
{
    return "JMX Controlled App";
}

@Override
public void start()
{
    // TODO: start application here
    System.out.println("remote start called");
}

@Override
public void stop()
{
    // TODO: stop application here
    System.out.println("remote stop called");

    m_thrd.interrupt();
}

public boolean isRunning()
{
    return Thread.currentThread().isAlive();
}

public static void main(String[] args)
{
    try
    {
        System.out.println("JMX started");

        ThreadMonitorMBean monitor = new ThreadMonitor(Thread.currentThread());

        MBeanServer server = ManagementFactory.getPlatformMBeanServer();

        ObjectName name = new ObjectName("com.example:type=ThreadMonitor");

        server.registerMBean(monitor, name);

        while(!Thread.interrupted())
        {
            // loop until interrupted
            System.out.println(".");
            try 
            {
                Thread.sleep(1000);
            } 
            catch(InterruptedException ex) 
            {
                Thread.currentThread().interrupt();
            }
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    finally
    {
        // TODO: some final clean up could be here also
        System.out.println("JMX stopped");
    }
}
}

অ্যাপ্লিকেশন নিয়ন্ত্রণ করছে: স্টপ
দিয়ে এটি চালান বা কমান্ড লাইন আর্গুমেন্ট হিসাবে শুরু করুন

public class ThreadMonitorConsole
{

public static void main(String[] args)
{
    try
    {   
        // connecting to JMX
        System.out.println("Connect to JMX service.");
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:9999/jmxrmi");
        JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
        MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

        // Construct proxy for the the MBean object
        ObjectName mbeanName = new ObjectName("com.example:type=ThreadMonitor");
        ThreadMonitorMBean mbeanProxy = JMX.newMBeanProxy(mbsc, mbeanName, ThreadMonitorMBean.class, true);

        System.out.println("Connected to: "+mbeanProxy.getName()+", the app is "+(mbeanProxy.isRunning() ? "" : "not ")+"running");

        // parse command line arguments
        if(args[0].equalsIgnoreCase("start"))
        {
            System.out.println("Invoke \"start\" method");
            mbeanProxy.start();
        }
        else if(args[0].equalsIgnoreCase("stop"))
        {
            System.out.println("Invoke \"stop\" method");
            mbeanProxy.stop();
        }

        // clean up and exit
        jmxc.close();
        System.out.println("Done.");    
    }
    catch(Exception e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
}


এটাই. :-)


7

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


3

এখানে কিছুটা জটিল, তবে বহনযোগ্য সমাধান:

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

আমি জাভা এজেন্ট প্রয়োগ করেছি। এটি গিথুব উপলভ্য: https://github.com/everit-org/javaagent-shutdown

সমাধান সম্পর্কে বিস্তারিত বিবরণ এখানে পাওয়া যায়: https://everitorg.wordpress.com/2016/06/15/shutting-down-a-jvm-process/


2

অনুরূপ প্রশ্ন এখানে

জাভার ফাইনালাইজাররা খারাপ। তারা আবর্জনা সংগ্রহের জন্য প্রচুর ওভারহেড যুক্ত করে। যখনই সম্ভব এগুলি এড়িয়ে চলুন।

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


4
তাহলে কি সব ক্ষেত্রেই শাটডাউনহুক ডাকা হবে? শেল থেকে প্রক্রিয়াটি 'হত্যা' হলে কী হবে?
Ma99uS

ঠিক আছে, আপনি যদি এটি কিল -9 দিচ্ছেন না :)
স্টিভ g

0

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

আপনার জাভা অ্যাপ্লিকেশনটিতে সকেট সার্ভারকে সংহত করে পোর্টেবল সিগন্যালিং করা যেতে পারে। এটি এতটা কঠিন নয় এবং আপনাকে যে কোনও আদেশ পাঠাতে স্বাধীনতা দেয়।

আপনি যদি চূড়ান্তভাবে চূড়ান্তকরণের স্থলে ধারাগুলি বোঝাতে চান; যখন System.exit () কল করা হয় তখন তারা নিখুঁত হয় না। ফাইনালাইজারদের কাজ করা উচিত তবে সত্যিকারের চেয়ে আরও গুরুত্বপূর্ণ কিছু করা উচিত নয় তবে একটি ডিবাগ স্টেটমেন্ট মুদ্রণ করা উচিত। তারা বিপজ্জনক


0

আপনার উত্তরের জন্য ধন্যবাদ। শাটডাউন হুকগুলি এমন কিছুর মতো সেলস দেয় যা আমার ক্ষেত্রে কাজ করবে। তবে আমি মনিটরিং অ্যান্ড ম্যানেজমেন্ট মটরশুটি নামে পরিচিত জিনিসটিও ছড়িয়ে দিয়েছি:
http://java.sun.com/j2se/1.5.0/docs/guide/management/overview.html
যা দূরবর্তী পর্যবেক্ষণ এবং হেরফেরের জন্য কিছু দুর্দান্ত সম্ভাবনা দেয় জাভা প্রক্রিয়া। (জাভা 5 এ চালু হয়েছিল)

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