Tidak ada cara platform-independen yang dapat dijamin untuk bekerja di semua implementasi jvm.
ManagementFactory.getRuntimeMXBean().getName()sepertinya solusi terbaik (terdekat). Ini pendek, dan mungkin bekerja di setiap implementasi yang digunakan secara luas.
Di linux + windows, ia mengembalikan nilai seperti 12345@hostname( 12345menjadi id proses). Namun berhati-hatilah bahwa menurut dokumen , tidak ada jaminan tentang nilai ini:
Mengembalikan nama yang mewakili mesin virtual Java yang sedang berjalan. String nama yang dikembalikan dapat berupa sembarang string dan implementasi mesin virtual Java dapat memilih untuk menanamkan informasi berguna platform-spesifik dalam string nama yang dikembalikan. Setiap mesin virtual yang berjalan dapat memiliki nama yang berbeda.
Di bawah Java 9 API proses baru dapat digunakan untuk mendapatkan ID proses saat ini. Pertama, Anda mengambil pegangan untuk proses saat ini, lalu meminta PID:
sangat bagus, baru diverifikasi bahwa ia berfungsi baik pada JRockit maupun JVM Hotspot.
Drupad Panchal
1
Penanganan yang bagus. Saya akan berasumsi ada alasan bagus mengapa metode ini (dan yang lainnya di kelas) tidak terbuka untuk umum dan mudah diakses, dan saya ingin tahu apa itu.
fragorl
2
Tim Oracle Java telah mengumumkan bahwa mereka bermaksud untuk menyembunyikan semua paket non-java (mis. Sun. *) Saya percaya memulai dengan Java 10 (dijadwalkan untuk 2018 - mungkin Java 9). Jika Anda memiliki implementasi yang serupa dengan yang di atas, Anda mungkin ingin mencari alternatif agar kode Anda tidak rusak.
hfontanez
Tidak berfungsi untuk saya baik karena matahari. * Paket mungkin dihapus atau tidak dapat diakses (VMManagement tidak dapat diselesaikan ke jenis).
Mike Stoddart
Karena cara kerja refleksi, akses ke manajemen matahari. * Tidak diperlukan. Lakukan saja getDeclaredMethodpada Objek yang dikembalikan oleh jvm.get(runtime).
Andrew T Finnell
36
Coba Sigar . API yang sangat luas. Lisensi Apache 2.
Anda akan memiliki lebih banyak upvotes jika Anda menjelaskan cara menggunakan SIGAR untuk ini
Brad Mace
1
Tautan rusak. Anda memberi contoh bagaimana menggunakan ini, tetapi apakah ada ketergantungan pakar untuk itu?
Jules
github.com/hyperic/sigar tampaknya merupakan lokasi yang dapat digunakan; ini juga menunjukkan bahwa itu kode asli dengan Java binding, yang mungkin membuatnya kurang dari solusi untuk banyak konteks.
Zastai
26
Metode berikut mencoba untuk mengekstrak PID dari java.lang.management.ManagementFactory:
privatestaticString getProcessId(finalString fallback){// Note: may fail in some JVM implementations// therefore fallback has to be provided// something like '<pid>@<hostname>', at least in SUN / Oracle JVMsfinalString jvmName =ManagementFactory.getRuntimeMXBean().getName();finalint index = jvmName.indexOf('@');if(index <1){// part before '@' empty (index = 0) / '@' not found (index = -1)return fallback;}try{returnLong.toString(Long.parseLong(jvmName.substring(0, index)));}catch(NumberFormatException e){// ignore}return fallback;}
VisualVM menggunakan kode serupa untuk mendapatkan PID mandiri, periksa com.sun.tools.visualvm.application.jvm.Jvm # ApplicationSupport # createCurrentApplication (). Mereka adalah para ahli, jadi sepertinya solusi lintas platform yang dapat diandalkan.
Espinosa
@Espinosa VisualVM hanya mendukung berjalan pada OpenJDK / Oracle / GraalVM JVM (pada 2020). Ini berarti mereka dapat membuat asumsi yang sesuai. Jika Anda melakukan hal yang sama, Anda menjadi tergantung pada vendor dan kode Anda dapat rusak jika dijalankan misalnya J9.
Thorbjørn Ravn Andersen
24
Untuk JVM yang lebih lama, di linux ...
privatestaticString getPid()throwsIOException{byte[] bo =newbyte[256];InputStream is =newFileInputStream("/proc/self/stat");
is.read(bo);for(int i =0; i < bo.length; i++){if((bo[i]<'0')||(bo[i]>'9')){returnnewString(bo,0, i);}}return"-1";}
Jika Anda akan melakukan itu, maka lakukan saja int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());. Mengapa girasi ekstra?
David Citron
2
Bagi yang penasaran, trik dalam komentar @vid benar-benar berfungsi. Adakah yang bisa mengatakan mengapa? Semacam sihir dalam getCanonicalFile()metode yang mengubah "diri" menjadi PID?
@DavidCitron +1! Anda benar, saya tidak berpikir di getCanonicalFile :-)
ggrandes
18
Anda dapat melihat proyek saya: JavaSysMon di GitHub. Ini memberikan id proses dan banyak hal lainnya (penggunaan CPU, penggunaan memori) lintas-platform (saat ini Windows, Mac OSX, Linux dan Solaris)
Bisakah Anda menjelaskan cara mendapatkan contoh Proses untuk proses yang sedang berjalan di Java 9?
Augusto
Jawaban yang bagus untuk menggunakan Java 9 pada 2016! Bisakah Anda menambahkan tautan ke javadocs? terima kasih
crazyGuy
8
Dalam Scala:
import sys.process._
val pid:Long=Seq("sh","-c","echo $PPID").!!.trim.toLong
Ini akan memberi Anda solusi pada sistem Unix sampai Java 9 akan dirilis. (Saya tahu, pertanyaannya adalah tentang Java, tetapi karena tidak ada pertanyaan yang setara untuk Scala, saya ingin meninggalkan ini untuk pengguna Scala yang mungkin tersandung ke pertanyaan yang sama.)
Yang terbaru yang saya temukan adalah bahwa ada sistem properti yang disebut sun.java.launcher.pidyang tersedia setidaknya di linux. Rencana saya adalah menggunakan itu dan jika tidak ditemukan menggunakan JMX bean.
Dalam kasus saya dengan Ubuntu 16.04 dan Java 8, ia mengembalikan null
david.perez
4
Tergantung di mana Anda mencari informasi.
Jika Anda mencari informasi dari konsol Anda dapat menggunakan perintah jps. Perintah memberikan output mirip dengan perintah ps Unix dan datang dengan JDK sejak saya percaya 1,5
Jika Anda melihat dari proses, RuntimeMXBean (seperti yang dikatakan oleh Wouter Coekaerts) mungkin merupakan pilihan terbaik Anda. Output dari getName () pada Windows menggunakan Sun JDK 1.6 u7 adalah dalam bentuk [PROCESS_ID] @ [MACHINE_NAME]. Namun Anda bisa mencoba mengeksekusi jps dan mem-parsing hasil dari itu:
String jps =[JDK HOME]+"\\bin\\jps.exe";Process p =Runtime.getRuntime().exec(jps);
Jika dijalankan tanpa opsi, output harus menjadi id proses diikuti dengan nama.
Alat JPS menggunakan perpustakaan jvmstat, bagian dari tools.jar. Lihat contoh saya atau lihat kode sumber JPS: grepcode.com/file_/repository.grepcode.com/java/root/jdk/… . Tidak perlu memanggil JPS sebagai proses eksternal, gunakan perpustakaan jvmstat secara langsung.
Espinosa
4
Ini adalah kode JConsole, dan berpotensi menggunakan jps dan VisualVM. Ini menggunakan kelas dari
sun.jvmstat.monitor.*paket, dari tool.jar.
Itu tool.jar adalah perpustakaan yang didistribusikan dengan Oracle JDK tetapi tidak JRE!
Kamu tidak bisa mendapatkan tool.jar dari repo Maven; mengkonfigurasinya dengan Maven agak sulit
Itu tool.jar mungkin mengandung tergantung platform (asli?) Kode sehingga tidak mudah didistribusikan
Ini berjalan dengan asumsi bahwa semua aplikasi JVM (lokal) "dipantau". Sepertinya dari Java 6 semua aplikasi pada umumnya (kecuali jika Anda secara aktif mengonfigurasi yang berlawanan)
Mungkin hanya berfungsi untuk Java 6+
Eclipse tidak menerbitkan kelas utama, jadi Anda tidak akan mendapatkan Eclipse PID dengan mudah Bug di MonitoredVmUtil?
UPDATE: Saya baru saja memeriksa ulang bahwa JPS menggunakan cara ini, yaitu perpustakaan Jvmstat (bagian dari tool.jar). Jadi tidak perlu memanggil JPS sebagai proses eksternal, panggil perpustakaan Jvmstat secara langsung seperti contoh saya. Anda juga dapat memperoleh daftar semua runnin JVM di localhost dengan cara ini. Lihat kode sumber JPS :
Berdasarkan jawaban Ashwin Jayaprakash (+1) tentang lisensi Apache 2.0 SIGAR, berikut adalah cara saya menggunakannya untuk hanya mendapatkan PID dari proses saat ini:
Saya tahu ini adalah utas lama, tetapi saya ingin memanggil bahwa API untuk mendapatkan PID (serta manipulasi lain dari proses Java saat runtime) sedang ditambahkan ke kelas Proses di JDK 9: http: // openjdk. java.net/jeps/102
Wow, itu cepat. Hanya butuh sekitar tujuh tahun! 😃
Dmitry Shechtman
1
Saya menemukan solusi yang mungkin sedikit kasus tepi dan saya tidak mencobanya pada OS lain selain Windows 10, tapi saya pikir itu layak diperhatikan.
Jika Anda menemukan diri Anda bekerja dengan J2V8 dan nodejs, Anda dapat menjalankan fungsi javascript sederhana dan mengembalikan Anda pid dari proses java.
Ini tidak memeriksa apakah pid digunakan, tetapi apakah pid sama dengan proses saat ini pid
c0der
Apa solusi yang tepat sehingga saya dapat memperbarui kode saya?
PartialData
-6
Inilah yang saya gunakan ketika saya memiliki persyaratan yang sama. Ini menentukan PID proses Java dengan benar. Biarkan kode java Anda menelurkan server pada nomor port yang telah ditentukan sebelumnya dan kemudian jalankan perintah OS untuk mengetahui mendengarkan PID pada port tersebut. Untuk Linux
Jawaban:
Tidak ada cara platform-independen yang dapat dijamin untuk bekerja di semua implementasi jvm.
ManagementFactory.getRuntimeMXBean().getName()
sepertinya solusi terbaik (terdekat). Ini pendek, dan mungkin bekerja di setiap implementasi yang digunakan secara luas.Di linux + windows, ia mengembalikan nilai seperti
12345@hostname
(12345
menjadi id proses). Namun berhati-hatilah bahwa menurut dokumen , tidak ada jaminan tentang nilai ini:Di Java 9 , API proses baru dapat digunakan:
sumber
Anda bisa menggunakan JNA . Sayangnya tidak ada API JNA umum untuk mendapatkan ID proses saat ini, tetapi setiap platform cukup sederhana:
Windows
Pastikan Anda sudah
jna-platform.jar
:Unix
Menyatakan:
Kemudian:
Jawa 9
Di bawah Java 9 API proses baru dapat digunakan untuk mendapatkan ID proses saat ini. Pertama, Anda mengambil pegangan untuk proses saat ini, lalu meminta PID:
sumber
getpid()
solusi juga bekerja untuk OS X, dengan panggilan JNA ke perpustakaan "Sistem".error: cannot find symbol
untuk jdk9Berikut adalah metode backdoor yang mungkin tidak berfungsi dengan semua VM tetapi harus bekerja pada linux dan windows ( contoh asli di sini ):
sumber
getDeclaredMethod
pada Objek yang dikembalikan olehjvm.get(runtime)
.Coba Sigar . API yang sangat luas. Lisensi Apache 2.
sumber
Metode berikut mencoba untuk mengekstrak PID dari
java.lang.management.ManagementFactory
:Panggil saja
getProcessId("<PID>")
, misalnya.sumber
Untuk JVM yang lebih lama, di linux ...
sumber
int pid = Integer.parseInt(new File("/proc/self").getCanonicalFile().getName());
. Mengapa girasi ekstra?getCanonicalFile()
metode yang mengubah "diri" menjadi PID?Anda dapat melihat proyek saya: JavaSysMon di GitHub. Ini memberikan id proses dan banyak hal lainnya (penggunaan CPU, penggunaan memori) lintas-platform (saat ini Windows, Mac OSX, Linux dan Solaris)
sumber
Karena Java 9 ada metode Process.getPid () yang mengembalikan ID asli suatu proses:
Untuk mendapatkan ID proses dari proses Java saat ini, seseorang dapat menggunakan
ProcessHandle
antarmuka:sumber
Dalam Scala:
Ini akan memberi Anda solusi pada sistem Unix sampai Java 9 akan dirilis. (Saya tahu, pertanyaannya adalah tentang Java, tetapi karena tidak ada pertanyaan yang setara untuk Scala, saya ingin meninggalkan ini untuk pengguna Scala yang mungkin tersandung ke pertanyaan yang sama.)
sumber
Untuk kelengkapan ada pembungkus di Spring Boot untuk
larutan. Jika bilangan bulat diperlukan, maka ini dapat disimpulkan hingga satu-baris:
Jika seseorang sudah menggunakan boot Spring, ia mungkin menggunakan org.springframework.boot.ApplicationPid
Metode toString () mencetak pid atau '???'.
Peringatan menggunakan ManagementFactory sudah dibahas dalam jawaban lain.
sumber
sumber
sumber
Yang terbaru yang saya temukan adalah bahwa ada sistem properti yang disebut
sun.java.launcher.pid
yang tersedia setidaknya di linux. Rencana saya adalah menggunakan itu dan jika tidak ditemukan menggunakanJMX bean
.sumber
Tergantung di mana Anda mencari informasi.
Jika Anda mencari informasi dari konsol Anda dapat menggunakan perintah jps. Perintah memberikan output mirip dengan perintah ps Unix dan datang dengan JDK sejak saya percaya 1,5
Jika Anda melihat dari proses, RuntimeMXBean (seperti yang dikatakan oleh Wouter Coekaerts) mungkin merupakan pilihan terbaik Anda. Output dari getName () pada Windows menggunakan Sun JDK 1.6 u7 adalah dalam bentuk [PROCESS_ID] @ [MACHINE_NAME]. Namun Anda bisa mencoba mengeksekusi jps dan mem-parsing hasil dari itu:
Jika dijalankan tanpa opsi, output harus menjadi id proses diikuti dengan nama.
sumber
Ini adalah kode JConsole, dan berpotensi menggunakan jps dan VisualVM. Ini menggunakan kelas dari
sun.jvmstat.monitor.*
paket, daritool.jar
.Ada beberapa tangkapan:
tool.jar
adalah perpustakaan yang didistribusikan dengan Oracle JDK tetapi tidak JRE!tool.jar
dari repo Maven; mengkonfigurasinya dengan Maven agak sulittool.jar
mungkin mengandung tergantung platform (asli?) Kode sehingga tidak mudah didistribusikanUPDATE: Saya baru saja memeriksa ulang bahwa JPS menggunakan cara ini, yaitu perpustakaan Jvmstat (bagian dari tool.jar). Jadi tidak perlu memanggil JPS sebagai proses eksternal, panggil perpustakaan Jvmstat secara langsung seperti contoh saya. Anda juga dapat memperoleh daftar semua runnin JVM di localhost dengan cara ini. Lihat kode sumber JPS :
sumber
Saya menambahkan ini, ke solusi lain.
dengan Java 10, untuk mendapatkannya
process id
sumber
Berdasarkan jawaban Ashwin Jayaprakash (+1) tentang lisensi Apache 2.0
SIGAR
, berikut adalah cara saya menggunakannya untuk hanya mendapatkan PID dari proses saat ini:Meskipun tidak bekerja di semua platform, ia bekerja di Linux, Windows, OS X dan berbagai platform Unix seperti yang tercantum di sini .
sumber
Anda dapat mencoba
getpid()
di JNR-Posix .Memiliki pembungkus Windows POSIX yang memanggil getpid () dari libc.
sumber
Saya tahu ini adalah utas lama, tetapi saya ingin memanggil bahwa API untuk mendapatkan PID (serta manipulasi lain dari proses Java saat runtime) sedang ditambahkan ke kelas Proses di JDK 9: http: // openjdk. java.net/jeps/102
sumber
Saya menemukan solusi yang mungkin sedikit kasus tepi dan saya tidak mencobanya pada OS lain selain Windows 10, tapi saya pikir itu layak diperhatikan.
Jika Anda menemukan diri Anda bekerja dengan J2V8 dan nodejs, Anda dapat menjalankan fungsi javascript sederhana dan mengembalikan Anda pid dari proses java.
Berikut ini sebuah contoh:
sumber
Inilah solusi saya:
sumber
Inilah yang saya gunakan ketika saya memiliki persyaratan yang sama. Ini menentukan PID proses Java dengan benar. Biarkan kode java Anda menelurkan server pada nomor port yang telah ditentukan sebelumnya dan kemudian jalankan perintah OS untuk mengetahui mendengarkan PID pada port tersebut. Untuk Linux
sumber
bash -c 'echo $PPID'
atau / proc jawaban di atas