मैं अपने जावा प्रोसेस की आईडी कैसे प्राप्त करूं?
मुझे पता है कि कई प्लेटफ़ॉर्म-निर्भर हैक हैं, लेकिन मैं अधिक सामान्य समाधान पसंद करूंगा।
मैं अपने जावा प्रोसेस की आईडी कैसे प्राप्त करूं?
मुझे पता है कि कई प्लेटफ़ॉर्म-निर्भर हैक हैं, लेकिन मैं अधिक सामान्य समाधान पसंद करूंगा।
जवाबों:
कोई भी प्लेटफ़ॉर्म-स्वतंत्र तरीका मौजूद नहीं है जिसे सभी jvm कार्यान्वयन में काम करने की गारंटी दी जा सकती है।
ManagementFactory.getRuntimeMXBean().getName()
सबसे अच्छा (निकटतम) समाधान जैसा दिखता है। यह छोटा है, और शायद व्यापक रूप से हर कार्यान्वयन में काम करता है।
Linux + windows पर यह एक मान देता है जैसे 12345@hostname
( 12345
प्रोसेस आईडी होना)। हालांकि , डॉक्स के अनुसार , इस मान के बारे में कोई गारंटी नहीं है:
चल रहे जावा वर्चुअल मशीन का प्रतिनिधित्व करने वाला नाम लौटाता है। लौटा हुआ नाम स्ट्रिंग किसी भी मनमाने ढंग से स्ट्रिंग हो सकता है और जावा वर्चुअल मशीन कार्यान्वयन लौटे नाम स्ट्रिंग में प्लेटफ़ॉर्म-विशिष्ट उपयोगी जानकारी एम्बेड करने का विकल्प चुन सकता है। प्रत्येक चलने वाली वर्चुअल मशीन का एक अलग नाम हो सकता है।
जावा 9 में नई प्रक्रिया एपीआई का उपयोग किया जा सकता है:
long pid = ProcessHandle.current().pid();
आप JNA का उपयोग कर सकते हैं । दुर्भाग्य से वर्तमान प्रक्रिया आईडी प्राप्त करने के लिए कोई सामान्य JNA API नहीं है, लेकिन प्रत्येक प्लेटफ़ॉर्म बहुत सरल है:
सुनिश्चित करें कि आपके पास jna-platform.jar
तब:
int pid = Kernel32.INSTANCE.GetCurrentProcessId();
घोषित:
private interface CLibrary extends Library {
CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);
int getpid ();
}
फिर:
int pid = CLibrary.INSTANCE.getpid();
जावा 9 के तहत वर्तमान प्रक्रिया आईडी प्राप्त करने के लिए नई प्रक्रिया एपीआई का उपयोग किया जा सकता है। पहले आप वर्तमान प्रक्रिया को हैंडल करते हैं, फिर PID को क्वेरी करते हैं:
long pid = ProcessHandle.current().pid();
getpid()
समाधान भी ओएस एक्स के लिए काम करता है, "सिस्टम" पुस्तकालय के लिए एक JNA कॉल के साथ।
error: cannot find symbol
jdk9 के लिए मिलता हूं
यहाँ एक पिछले दरवाजे की विधि है जो सभी वीएम के साथ काम नहीं कर सकती है लेकिन यह लिनक्स और विंडोज़ ( मूल उदाहरण ) दोनों पर काम करना चाहिए :
java.lang.management.RuntimeMXBean runtime =
java.lang.management.ManagementFactory.getRuntimeMXBean();
java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
jvm.setAccessible(true);
sun.management.VMManagement mgmt =
(sun.management.VMManagement) jvm.get(runtime);
java.lang.reflect.Method pid_method =
mgmt.getClass().getDeclaredMethod("getProcessId");
pid_method.setAccessible(true);
int pid = (Integer) pid_method.invoke(mgmt);
getDeclaredMethod
गए ऑब्जेक्ट पर प्रदर्शन करें jvm.get(runtime)
।
सिगार का प्रयास करें । बहुत व्यापक एपीआई। अपाचे 2 लाइसेंस।
private Sigar sigar;
public synchronized Sigar getSigar() {
if (sigar == null) {
sigar = new Sigar();
}
return sigar;
}
public synchronized void forceRelease() {
if (sigar != null) {
sigar.close();
sigar = null;
}
}
public long getPid() {
return getSigar().getPid();
}
निम्न विधि PID को निकालने का प्रयास करती है java.lang.management.ManagementFactory
:
private static String getProcessId(final String fallback) {
// Note: may fail in some JVM implementations
// therefore fallback has to be provided
// something like '<pid>@<hostname>', at least in SUN / Oracle JVMs
final String jvmName = ManagementFactory.getRuntimeMXBean().getName();
final int index = jvmName.indexOf('@');
if (index < 1) {
// part before '@' empty (index = 0) / '@' not found (index = -1)
return fallback;
}
try {
return Long.toString(Long.parseLong(jvmName.substring(0, index)));
} catch (NumberFormatException e) {
// ignore
}
return fallback;
}
getProcessId("<PID>")
उदाहरण के लिए, बस कॉल करें ।
पुराने JVM के लिए, linux में ...
private static String getPid() throws IOException {
byte[] bo = new byte[256];
InputStream is = new FileInputStream("/proc/self/stat");
is.read(bo);
for (int i = 0; i < bo.length; i++) {
if ((bo[i] < '0') || (bo[i] > '9')) {
return new String(bo, 0, i);
}
}
return "-1";
}
int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
। क्यों अतिरिक्त gyrations?
getCanonicalFile()
जो "स्वयं" को पीआईडी में परिवर्तित करता है?
आप मेरे प्रोजेक्ट को देख सकते हैं: GitHub पर JavaSysMon । यह प्रक्रिया आईडी और अन्य सामान का एक गुच्छा (सीपीयू उपयोग, मेमोरी उपयोग) क्रॉस-प्लेटफॉर्म (वर्तमान में विंडोज, मैक ओएसएक्स, लिनक्स और सोलारिस) प्रदान करता है
Java 9 के बाद से एक मेथड Process.getPid () है जो किसी प्रक्रिया की मूल आईडी लौटाता है:
public abstract class Process {
...
public long getPid();
}
वर्तमान जावा प्रक्रिया की प्रक्रिया आईडी प्राप्त करने के लिए कोई ProcessHandle
इंटरफ़ेस का उपयोग कर सकता है:
System.out.println(ProcessHandle.current().pid());
स्काला में:
import sys.process._
val pid: Long = Seq("sh", "-c", "echo $PPID").!!.trim.toLong
यह आपको यूनिक्स सिस्टम पर एक वर्कअराउंड देना चाहिए जब तक कि जावा 9 जारी नहीं किया जाएगा। (मुझे पता है, सवाल जावा के बारे में था, लेकिन चूंकि स्काला के लिए कोई समकक्ष प्रश्न नहीं है, इसलिए मैं इसे स्काला उपयोगकर्ताओं के लिए छोड़ना चाहता था जो एक ही प्रश्न में ठोकर खा सकते हैं।)
पूर्णता के लिए वहाँ में एक आवरण है वसंत बूट के लिए
String jvmName = ManagementFactory.getRuntimeMXBean().getName();
return jvmName.split("@")[0];
समाधान। यदि एक पूर्णांक की आवश्यकता होती है, तो इसे एक-लाइनर तक सम्मिलित किया जा सकता है:
int pid = Integer.parseInt(ManagementFactory.getRuntimeMXBean().getName().split("@")[0]);
यदि कोई पहले से ही स्प्रिंग बूट का उपयोग करता है, तो वह org.springframework.boot.ApplicationPid का उपयोग कर सकता है
ApplicationPid pid = new ApplicationPid();
pid.toString();
TheString () विधि pid या '???' को प्रिंट करती है।
ManagementFactory का उपयोग करने वाले कैविट्स अन्य उत्तरों में पहले से ही चर्चा कर रहे हैं।
नवीनतम मैंने पाया है कि एक प्रणाली गुण है जिसे कहा जाता है sun.java.launcher.pid
जो कम से कम लिनक्स पर उपलब्ध है। मेरी योजना का उपयोग करना है और यदि इसका उपयोग नहीं किया जाता है JMX bean
।
यह इस बात पर निर्भर करता है कि आप कहां से जानकारी की तलाश कर रहे हैं।
यदि आप कंसोल से जानकारी ढूंढ रहे हैं तो आप jps कमांड का उपयोग कर सकते हैं। कमांड यूनिक्स पीएस कमांड के समान आउटपुट देता है और जेडडीके के साथ आता है क्योंकि मैं 1.5 मानता हूं
यदि आप RuntimeMXBean (Wouter Coekaerts द्वारा कहा गया है) प्रक्रिया से देख रहे हैं, तो शायद यह आपका सबसे अच्छा विकल्प है। Sun JDK 1.6 u7 का उपयोग कर विंडोज पर getName () से आउटपुट फॉर्म [PROCESS_ID] @ [MACHINE_NAME] के रूप में है। हालाँकि आप jps को अंजाम देने की कोशिश कर सकते हैं और उससे परिणाम को पार कर सकते हैं:
String jps = [JDK HOME] + "\\bin\\jps.exe";
Process p = Runtime.getRuntime().exec(jps);
यदि कोई विकल्प नहीं है तो आउटपुट को नाम के बाद प्रोसेस आईडी होना चाहिए।
यह कोड JConsole, और संभावित jps और VisualVM का उपयोग करता है। यह sun.jvmstat.monitor.*
संकुल से, से कक्षाओं का उपयोग करता
है tool.jar
।
package my.code.a003.process;
import sun.jvmstat.monitor.HostIdentifier;
import sun.jvmstat.monitor.MonitorException;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredVm;
import sun.jvmstat.monitor.MonitoredVmUtil;
import sun.jvmstat.monitor.VmIdentifier;
public class GetOwnPid {
public static void main(String[] args) {
new GetOwnPid().run();
}
public void run() {
System.out.println(getPid(this.getClass()));
}
public Integer getPid(Class<?> mainClass) {
MonitoredHost monitoredHost;
Set<Integer> activeVmPids;
try {
monitoredHost = MonitoredHost.getMonitoredHost(new HostIdentifier((String) null));
activeVmPids = monitoredHost.activeVms();
MonitoredVm mvm = null;
for (Integer vmPid : activeVmPids) {
try {
mvm = monitoredHost.getMonitoredVm(new VmIdentifier(vmPid.toString()));
String mvmMainClass = MonitoredVmUtil.mainClass(mvm, true);
if (mainClass.getName().equals(mvmMainClass)) {
return vmPid;
}
} finally {
if (mvm != null) {
mvm.detach();
}
}
}
} catch (java.net.URISyntaxException e) {
throw new InternalError(e.getMessage());
} catch (MonitorException e) {
throw new InternalError(e.getMessage());
}
return null;
}
}
कुछ कैच हैं:
tool.jar
एक पुस्तकालय ओरेकल JDK नहीं बल्कि JRE के साथ वितरित है!tool.jar
मावेन रेपो से नहीं मिल सकते ; मावेन के साथ इसे कॉन्फ़िगर करना थोड़ा मुश्किल हैtool.jar
शायद मंच निर्भर (देशी?) कोड शामिल तो यह आसानी से वितरण योग्य नहीं हैअद्यतन: मैंने अभी-अभी डबल चेक किया है कि JPS इस तरह से उपयोग करता है, वह है Jvmstat पुस्तकालय (tool.jar का हिस्सा)। इसलिए जेपीएस को बाहरी प्रक्रिया के रूप में कॉल करने की आवश्यकता नहीं है, मेरे उदाहरण के रूप में सीधे Jvmstat पुस्तकालय को कॉल करें। आप इस तरह से लोकलहोस्ट पर सभी JVM रनरिन की सूची प्राप्त कर सकते हैं। जेपीएस स्रोत कोड देखें :
मैं इसे अन्य समाधानों में जोड़ रहा हूं।
process id
final RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
final long pid = runtime.getPid();
out.println("Process ID is '" + pid);
अपाचे 2.0 के लाइसेंस के बारे में अश्विन जयप्रकाश के जवाब (+1) के आधार पर SIGAR
, यहां बताया गया है कि मैं इसका इस्तेमाल मौजूदा प्रक्रिया के केवल पीआईडी पाने के लिए कैसे कर सकता हूं:
import org.hyperic.sigar.Sigar;
Sigar sigar = new Sigar();
long pid = sigar.getPid();
sigar.close();
भले ही यह सभी प्लेटफार्मों पर काम नहीं करता है, यह यहां सूचीबद्ध के रूप में लिनक्स, विंडोज, ओएस एक्स और विभिन्न यूनिक्स प्लेटफार्मों पर काम करता है ।
मुझे पता है कि यह एक पुराना धागा है, लेकिन मैं पीआईडी पाने के लिए उस एपीआई को कॉल करना चाहता था (साथ ही रनटाइम में जावा प्रक्रिया के अन्य हेरफेर) को जेडीके 9: http: // openjdk में प्रोसेस क्लास में जोड़ा जा रहा है । java.net/jeps/102
मुझे एक समाधान मिला जो एक किनारे का मामला हो सकता है और मैंने इसे विंडोज़ 10 के अलावा अन्य ओएस पर नहीं आज़माया था, लेकिन मुझे लगता है कि यह ध्यान देने योग्य है।
यदि आप अपने आप को काम के साथ पाते हैं J2V8 और नोडज के हुए पाते हैं, तो आप एक साधारण जावास्क्रिप्ट फंक्शन चला सकते हैं, जो आपको जावा प्रक्रिया के लिए वापस लौटा देगा।
यहाँ एक उदाहरण है:
public static void main(String[] args) {
NodeJS nodeJS = NodeJS.createNodeJS();
int pid = nodeJS.getRuntime().executeIntegerScript("process.pid;\n");
System.out.println(pid);
nodeJS.release();
}
यहाँ मेरा समाधान है:
public static boolean isPIDInUse(int pid) {
try {
String s = null;
int java_pid;
RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
java_pid = Integer.parseInt(rt.getName().substring(0, rt.getName().indexOf("@")));
if (java_pid == pid) {
System.out.println("In Use\n");
return true;
}
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
return false;
}
यह वही है जो मैंने उपयोग किया था जब मुझे इसी तरह की आवश्यकता थी। यह जावा प्रक्रिया के पीआईडी को सही ढंग से निर्धारित करता है। अपने जावा कोड को पूर्व-परिभाषित पोर्ट नंबर पर एक सर्वर को स्पॉन करें और फिर पोर्ट पर सुन रहे पीआईडी का पता लगाने के लिए ओएस कमांड निष्पादित करें। लिनक्स के लिए
netstat -tupln | grep portNumber
bash -c 'echo $PPID'
/ या उत्तर के ऊपर खरीद