2008-10-10 41 views
82

मैं जावा प्रक्रिया को लिनक्स और विंडोज में गहन तरीके से कैसे रोकूं?जावा प्रक्रिया को कैसे रोकें?

Runtime.getRuntime().addShutdownHook कब कॉल किया जाता है, और यह कब नहीं होता है?

अंतिमकर्ताओं के बारे में क्या, क्या वे यहां सहायता करते हैं?

क्या मैं एक शैल से जावा प्रक्रिया में कुछ प्रकार का सिग्नल भेज सकता हूं?

मैं अधिमानतः पोर्टेबल समाधान की तलाश में हूं।

+0

तुम सच में आप शान से से क्या मतलब है परिभाषित करना चाहिए। (कृपया) –

+6

मुझे लगता है कि उनका मतलब है कि वे संसाधनों को छोड़ने से पहले संसाधनों को छोड़ने, रिलीज, ताले और किसी भी लगातार डेटा को फ्लश करने का मौका देना चाहते हैं। –

उत्तर

72

शटडाउन हुक सभी मामलों में निष्पादित करते हैं जहां वीएम जबरन मार डाला नहीं जाता है। इसलिए, यदि आप एक "मानक" हत्या (SIGTERM को मार कमांड से जारी करना चाहते थे) तो वे निष्पादित करेंगे। इसी प्रकार, वे System.exit(int) पर कॉल करने के बाद निष्पादित करेंगे।

हालांकि एक कठिन मार (kill -9 या kill -SIGKILL) तो वे निष्पादित नहीं होंगे। इसी प्रकार (और स्पष्ट रूप से) यदि आप कंप्यूटर से बिजली खींचते हैं, तो इसे निष्पादित नहीं करेंगे, इसे उबलते लावा के एक भाग में छोड़ दें, या सीपीयू को स्लेजहैमर के साथ टुकड़ों में हराएं। आप शायद पहले से ही जानते थे कि, हालांकि।

अंतिमकर्ताओं को वास्तव में भी चलना चाहिए, लेकिन शटडाउन क्लीनअप के लिए उस पर भरोसा करना सबसे अच्छा नहीं है, बल्कि चीजों को साफ करने के लिए अपने शटडाउन हुक पर भरोसा करना है। और, हमेशा के रूप में, deadlocks से सावधान रहें (मैंने देखा है कि बहुत सारी शटडाउन हुक पूरी प्रक्रिया लटका है)!

+0

दुर्भाग्यवश, यह विंडोज 7 (64 बिट) पर काम नहीं कर रहा है। मैंने फोर्स फ्लैग के बिना टास्किल का उपयोग करने का प्रयास किया है, और निम्न त्रुटि का सामना करना पड़ता है: "त्रुटि: पीआईडी ​​14324 के साथ प्रक्रिया को समाप्त नहीं किया जा सका। कारण: इस प्रक्रिया को केवल बलपूर्वक समाप्त किया जा सकता है (साथ/एफ विकल्प)।" बल विकल्प की आपूर्ति, "/ एफ", स्पष्ट रूप से प्रक्रिया को तुरंत बंद कर देगा। –

+0

आप अंतिम बार चलाने वाले पर भरोसा नहीं कर सकते हैं। –

2

इसी प्रकार के प्रश्न जावा में Here

finalizers बुरा कर रहे हैं। वे कचरा संग्रह में बहुत अधिक उपर जोड़ते हैं। जब भी संभव हो उन्हें से बचें।

शटडाउन केवल वीएम बंद होने पर ही कॉल किया जाएगा। मुझे लगता है कि यह वही कर सकता है जो आप चाहते हैं।

+1

तो शट डाउन हुक सभी मामलों में बुलाया जाता है? अगर शेल से प्रक्रिया को मार डालें तो क्या होगा? – Ma99uS

+0

अच्छा, अगर आप इसे एक हत्या -9 दे रहे हैं :) –

0

सिग्नलिंग "मारने" (आदमी उपलब्ध संकेतों के लिए मारने के) के साथ किया जा सकता है, आप ऐसा करने के लिए प्रक्रिया ID आवश्यकता होगी। (पीएस कुल्हाड़ी | grep java) या ऐसा कुछ, या जब प्रक्रिया बनाई जाती है तो प्रक्रिया आईडी को स्टोर करें (यह अधिकांश लिनक्स स्टार्टअप फ़ाइलों में उपयोग किया जाता है, देखें /etc/init.d)

पोर्टेबल सिग्नलिंग द्वारा किया जा सकता है अपने जावा एप्लिकेशन में सॉकेटसेवर को एकीकृत करना। यह मुश्किल नहीं है और आपको इच्छित आदेश भेजने की आजादी देता है।

यदि आप अंततः अंतिमकर्ताओं के स्थिर होने के खंड में थे; System.exit() को कॉल करते समय वे निष्कासित नहीं होते हैं। फाइनल को काम करना चाहिए, लेकिन वास्तव में कुछ और महत्वपूर्ण नहीं करना चाहिए लेकिन एक डीबग कथन मुद्रित करना चाहिए। वे खतरनाक हैं।

0

आपके उत्तर के लिए धन्यवाद। शटडाउन हुक कुछ ऐसे चीज की तरह है जो मेरे मामले में काम करेगा। लेकिन मैंने मॉनीटरिंग और मैनेजमेंट बीन्स नामक चीज में भी टक्कर लगी:
http://java.sun.com/j2se/1.5.0/docs/guide/management/overview.html
यह रिमोट मॉनिटरिंग और जावा प्रक्रिया में हेरफेर के लिए कुछ अच्छी संभावनाएं देता है।, (जावा 5 में पेश किया गया)

46

ठीक है सभी संभावनाओं मैं "जावा निगरानी और प्रबंधन"
Overview is here
आप अपेक्षाकृत आसान तरीका में एक दूसरे से एक आवेदन को नियंत्रित करने के लिए अनुमति देता है कि साथ काम करने के लिए चुना है के बाद। आप इसे नियंत्रित करने से पहले नियंत्रित अनुप्रयोग को गर्व से रोकने के लिए एक स्क्रिप्ट से नियंत्रण अनुप्रयोग को कॉल कर सकते हैं।

यहाँ सरलीकृत कोड है:

नियंत्रित आवेदन:
folowing वीएम मानकों के साथ रन यह:
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote .port = 9999
-Dcom.sun.management.jmxremote.authenticate = false
-Dcom.sun.management.jmxremote.ssl = false

//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()। आप टेलनेट जैसे बाहरी एप्लिकेशन का उपयोग करके सॉकेट को ऐसी जानकारी भेज सकते हैं।

1

यहाँ थोड़ा मुश्किल है, लेकिन पोर्टेबल समाधान:

  • अपने आवेदन में एक बंद हुक
  • लागू आप शान से अपने JVM बंद करने के लिए, एक Java Agent कि System.exit कॉल स्थापित करना चाहते हैं ()Attach API का उपयोग कर।

मैंने जावा एजेंट को लागू किया। यह Github पर उपलब्ध है: https://github.com/everit-org/javaagent-shutdown

समाधान के बारे में विस्तृत विवरण यहाँ उपलब्ध है: https://everitorg.wordpress.com/2016/06/15/shutting-down-a-jvm-process/

संबंधित मुद्दे