Bagaimana cara memeriksa Penggunaan CPU dan Memori di Java?


Jawaban:


73

Jika Anda mencari memori khusus di JVM:

Runtime runtime = Runtime.getRuntime();

NumberFormat format = NumberFormat.getInstance();

StringBuilder sb = new StringBuilder();
long maxMemory = runtime.maxMemory();
long allocatedMemory = runtime.totalMemory();
long freeMemory = runtime.freeMemory();

sb.append("free memory: " + format.format(freeMemory / 1024) + "<br/>");
sb.append("allocated memory: " + format.format(allocatedMemory / 1024) + "<br/>");
sb.append("max memory: " + format.format(maxMemory / 1024) + "<br/>");
sb.append("total free memory: " + format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024) + "<br/>");

Namun, ini harus dianggap hanya sebagai perkiraan ...


Jadi, jika saya menjalankan di Eclipse, ini akan bergantung pada setelan Eclipse saya?
Kopi

4
Perhatikan bahwa ini bukan memori yang digunakan sebenarnya- ini adalah 'memori yang dialokasikan' yang berarti heap yang telah dialokasikan java, jadi jika Anda memiliki -Xms90g dan aplikasi Anda sangat ringan, Anda masih akan mendapatkan alokasiMemory sebagai sesuatu yang lebih besar dari 90g . Lihat jawaban dengan menghapus "tidak diketahui (yahoo)" di bawah (yang mungkin berbeda pada pandangan pertama)
0fnt

Penasaran saja, kenapa ini hanya perkiraan saja?
ComputerScientist

@ComputerScientist Karena gratis sebenarnya adalah apa yang gratis (posting GC), ia tidak menampilkan objek yang menunggu GC. Untuk mendapatkan JAUH lebih akurat, jalankan 2 kumpulan sampah sebelum jawaban ini. Jika Anda mencobanya dengan dan tanpa GC, Anda akan menemukan nilai pasca-GC sangat konsisten tetapi preGC umumnya setidaknya akan menggandakannya.
Bill K

@sbeliakov Anda dapat menggunakan JavaSysmon ( github.com/jezhumble/javasysmon ), meskipun saya sarankan Anda membuka pertanyaan baru dan saya akan menjawabnya. Library di GitHub memiliki bug dan mengenali 32 bit sebagai 64 bit, tetapi saya menemukan solusi untuk mencampur berbagai jars [ github.com/goxr3plus/XR3Player/blob/master/resources/libs/… ].
GOXR3PLUS

20
package mkd.Utils;

import java.io.File;
import java.text.NumberFormat;

public class systemInfo {

    private Runtime runtime = Runtime.getRuntime();

    public String Info() {
        StringBuilder sb = new StringBuilder();
        sb.append(this.OsInfo());
        sb.append(this.MemInfo());
        sb.append(this.DiskInfo());
        return sb.toString();
    }

    public String OSname() {
        return System.getProperty("os.name");
    }

    public String OSversion() {
        return System.getProperty("os.version");
    }

    public String OsArch() {
        return System.getProperty("os.arch");
    }

    public long totalMem() {
        return Runtime.getRuntime().totalMemory();
    }

    public long usedMem() {
        return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
    }

    public String MemInfo() {
        NumberFormat format = NumberFormat.getInstance();
        StringBuilder sb = new StringBuilder();
        long maxMemory = runtime.maxMemory();
        long allocatedMemory = runtime.totalMemory();
        long freeMemory = runtime.freeMemory();
        sb.append("Free memory: ");
        sb.append(format.format(freeMemory / 1024));
        sb.append("<br/>");
        sb.append("Allocated memory: ");
        sb.append(format.format(allocatedMemory / 1024));
        sb.append("<br/>");
        sb.append("Max memory: ");
        sb.append(format.format(maxMemory / 1024));
        sb.append("<br/>");
        sb.append("Total free memory: ");
        sb.append(format.format((freeMemory + (maxMemory - allocatedMemory)) / 1024));
        sb.append("<br/>");
        return sb.toString();

    }

    public String OsInfo() {
        StringBuilder sb = new StringBuilder();
        sb.append("OS: ");
        sb.append(this.OSname());
        sb.append("<br/>");
        sb.append("Version: ");
        sb.append(this.OSversion());
        sb.append("<br/>");
        sb.append(": ");
        sb.append(this.OsArch());
        sb.append("<br/>");
        sb.append("Available processors (cores): ");
        sb.append(runtime.availableProcessors());
        sb.append("<br/>");
        return sb.toString();
    }

    public String DiskInfo() {
        /* Get a list of all filesystem roots on this system */
        File[] roots = File.listRoots();
        StringBuilder sb = new StringBuilder();

        /* For each filesystem root, print some info */
        for (File root : roots) {
            sb.append("File system root: ");
            sb.append(root.getAbsolutePath());
            sb.append("<br/>");
            sb.append("Total space (bytes): ");
            sb.append(root.getTotalSpace());
            sb.append("<br/>");
            sb.append("Free space (bytes): ");
            sb.append(root.getFreeSpace());
            sb.append("<br/>");
            sb.append("Usable space (bytes): ");
            sb.append(root.getUsableSpace());
            sb.append("<br/>");
        }
        return sb.toString();
    }
}

Pemahaman saya bahwa topik yang dimulai adalah menanyakan tentang jumlah memori yang tersedia di OS. freeMemorydi sini mengembalikan jumlah memori yang tersedia di JVM yang sangat berbeda
Tagar

Bukankah aneh bahwa kelas Anda SystemInfo tidak dimulai dengan Modal dan metode Anda Info (), OSname (), MemInfo () lakukan?
Drswaki69

18

Jika Anda menggunakan Sun JVM, dan tertarik dengan penggunaan memori internal aplikasi (berapa banyak dari memori yang dialokasikan yang digunakan aplikasi Anda), saya lebih suka mengaktifkan pencatatan pengumpulan sampah bawaan JVM. Anda cukup menambahkan -verbose: gc ke perintah startup.

Dokumentasi Dari Matahari:

Argumen baris perintah -verbose: gc mencetak informasi di setiap koleksi. Perhatikan bahwa format output -verbose: gc dapat berubah sewaktu-waktu di antara rilis platform J2SE. Misalnya, berikut adalah keluaran dari aplikasi server besar:

[GC 325407K->83000K(776768K), 0.2300771 secs]
[GC 325816K->83372K(776768K), 0.2454258 secs]
[Full GC 267628K->83769K(776768K), 1.8479984 secs]

Di sini kita melihat dua koleksi kecil dan satu koleksi besar. Angka-angka sebelum dan sesudah panah

325407K->83000K (in the first line)

menunjukkan ukuran gabungan dari objek aktif sebelum dan sesudah pengumpulan sampah. Setelah koleksi kecil, penghitungan mencakup objek yang belum tentu hidup tetapi tidak dapat diklaim kembali, baik karena benda tersebut hidup secara langsung, atau karena berada di dalam atau dirujuk dari generasi bertenor. Angka dalam tanda kurung

(776768K) (in the first line)

adalah total ruang yang tersedia, tidak termasuk ruang pada generasi permanen, yang merupakan total heap dikurangi satu ruang yang selamat. Pengumpulan kecil membutuhkan waktu sekitar seperempat detik.

0.2300771 secs (in the first line)

Untuk info lebih lanjut lihat: http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html


17

Dari sini

    OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
    RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
    int availableProcessors = operatingSystemMXBean.getAvailableProcessors();
    long prevUpTime = runtimeMXBean.getUptime();
    long prevProcessCpuTime = operatingSystemMXBean.getProcessCpuTime();
    double cpuUsage;
    try
    {
        Thread.sleep(500);
    }
    catch (Exception ignored) { }

    operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
    long upTime = runtimeMXBean.getUptime();
    long processCpuTime = operatingSystemMXBean.getProcessCpuTime();
    long elapsedCpu = processCpuTime - prevProcessCpuTime;
    long elapsedTime = upTime - prevUpTime;

    cpuUsage = Math.min(99F, elapsedCpu / (elapsedTime * 10000F * availableProcessors));
    System.out.println("Java CPU: " + cpuUsage);

1
Dan tentang ingatannya?
Daniel De León

2
Daftar <MemoryPoolMXBean> memoryPools = new ArrayList <MemoryPoolMXBean> (ManagementFactory.getMemoryPoolMXBeans ()); long usedHeapMemoryAfterLastGC = 0; untuk (MemoryPoolMXBean memoryPool: memoryPools) {if (memoryPool.getType (). sama dengan (MemoryType.HEAP)) {MemoryUsage poolCollectionMemoryUsage = memoryPool.getCollectionUsage (); usedHeapMemoryAfterLastGC + = poolCollectionMemoryUsage.getUsed (); }}
danieln

1
Terima kasih atas satu-satunya jawaban yang menampilkan pengambilan penggunaan CPU.
Matthieu

1
Apa perbedaan antara melakukan ini dan sekadar melakukan operatingSystemMXBean.getProcessCpuLoad();? Menurut dokumentasi Oracle, metode ini mengembalikan "Mengembalikan" penggunaan cpu terkini "untuk proses Java Virtual Machine." Namun saya melihat perbedaan jumlah yang relatif besar antara metode Anda dan metode ini.
Ishnark

1
@RobHall Ada dua OperatingSystemMXBeankelas. Salah satunya adalah antarmuka yang disediakan di java.lang. Tapi ada juga versi lain, yang memperpanjang versi ini com.sun.management. Itulah metode yang saya maksud adalah dari ituOperatingSystemMXBean
Ishnark

9

JMX, MXBeans (ThreadMXBean, dll) yang disediakan akan memberi Anda penggunaan Memori dan CPU.

OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
operatingSystemMXBean.getSystemCpuLoad();

8

Untuk penggunaan memori, berikut ini akan berfungsi,

long total = Runtime.getRuntime().totalMemory();
long used  = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

Untuk penggunaan CPU, Anda perlu menggunakan aplikasi eksternal untuk mengukurnya.


6

Sejak Java 1.5, JDK hadir dengan alat baru: JConsole yang dapat menunjukkan penggunaan CPU dan memori dari JVM 1.5 atau yang lebih baru. Itu dapat melakukan grafik parameter ini, mengekspor ke CSV, menunjukkan jumlah kelas yang dimuat, jumlah instance, kebuntuan, utas, dll ...


4

Jika Anda menggunakan solusi runtime / totalMemory yang telah diposting di banyak jawaban di sini (saya sudah sering melakukannya), pastikan untuk memaksa dua kumpulan sampah terlebih dahulu jika Anda menginginkan hasil yang cukup akurat / konsisten.

Untuk efisiensi, Java biasanya mengizinkan sampah mengisi semua memori sebelum memaksakan GC, dan bahkan GC biasanya bukan GC lengkap, jadi hasil Anda untuk runtime.freeMemory () selalu berada di antara jumlah "sebenarnya" dari memori bebas dan 0 .

GC pertama tidak mendapatkan segalanya, ia mendapatkan sebagian besar darinya.

Peningkatannya adalah jika Anda hanya melakukan panggilan freeMemory () Anda akan mendapatkan nomor yang sama sekali tidak berguna dan sangat bervariasi, tetapi jika melakukan 2 gc pertama, itu adalah pengukur yang sangat andal. Itu juga membuat JAUH rutin lebih lambat (detik, mungkin).


3

Objek Runtime Java dapat melaporkan penggunaan memori JVM. Untuk konsumsi CPU, Anda harus menggunakan utilitas eksternal, seperti bagian atas Unix atau Manajer Proses Windows.


2

JConsole adalah cara mudah untuk memantau aplikasi Java yang sedang berjalan atau Anda dapat menggunakan Profiler untuk mendapatkan informasi lebih rinci tentang aplikasi Anda. Saya suka menggunakan NetBeans Profiler untuk ini.


2

Berikut beberapa kode sederhana untuk menghitung penggunaan memori saat ini dalam megabyte:

double currentMemory = ( (double)((double)(Runtime.getRuntime().totalMemory()/1024)/1024))- ((double)((double)(Runtime.getRuntime().freeMemory()/1024)/1024));

2

Saya juga akan menambahkan cara berikut untuk melacak Beban CPU:

import java.lang.management.ManagementFactory;
import com.sun.management.OperatingSystemMXBean;

double getCpuLoad() {
    OperatingSystemMXBean osBean =
        (com.sun.management.OperatingSystemMXBean) ManagementFactory.
        getPlatformMXBeans(OperatingSystemMXBean.class);
    return osBean.getProcessCpuLoad();
}

Anda dapat membaca lebih lanjut di sini



1

Jika Anda menggunakan Tomcat, lihat Psi Probe , yang memungkinkan Anda memantau konsumsi memori internal dan eksternal serta sejumlah area lainnya.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.