如何检查Java中的CPU和内存使用情况?


Answers:


73

如果您正在专门寻找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/>");

但是,这些仅应作为估计...


因此,如果我在Eclipse中运行,这取决于我的Eclipse设置吗?
2013年

4
请注意,这不是实际使用的内存-这是“已分配的内存”,这意味着java已分配的堆,因此,如果您具有-Xms90g,并且您的应用程序非常轻巧,那么您仍然会获得分配的内存,其内存大于90g 。请参阅下面删除的“未知(yahoo)”答案(乍一看可能会有所不同)
0fnt

只是好奇,为什么这些仅仅是估计?
ComputerScientist

@ComputerScientist因为免费实际上是免费的(在GC之后),所以它不显示等待GC的对象。为了更准确,请在此答案之前运行2个垃圾回收。如果在不使用GC的情况下进行尝试,您会发现GC后的值非常一致,但preGC通常至少是其两倍。
比尔K

@sbeliakov您可以使用JavaSysmon(github.com/jezhumble/javasysmon),尽管我建议您打开一个新问题,然后我会回答。GitHub上的库有一个错误,可以将32位识别为64位,但是我发现了混合不同jar的工作[ 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();
    }
}

我对主题开始的理解是询问操作系统中可用的内存量。freeMemory这里返回的JVM中可用的内存量非常不同
Tagar

您的类SystemInfo不是以大写字母开头并且您的方法Info(),OSname()和MemInfo()这样做不是很奇怪吗?
Drswaki69

18

如果您使用的是Sun JVM,并且对应用程序的内部内存使用情况(应用程序使用的已分配内存中的多少)感兴趣,则我更喜欢打开JVM的内置垃圾收集日志记录。您只需在启动命令中添加-verbose:gc即可。

从Sun文档:

命令行参数-verbose:gc在每个集合中打印信息。注意,-verbose:gc输出的格式在J2SE平台的发行版之间可能会发生变化。例如,以下是大型服务器应用程序的输出:

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

在这里,我们看到了两个次要收藏,一个主要收藏。箭头前后的数字

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

分别指示垃圾回收之前和之后的活动对象的组合大小。在进行次要收集之后,计数中包括不一定处于活动状态但无法回收的对象,这是因为它们是直接存在的,或者是因为它们在受权保护的代之内或从其继承而来。括号内的数字

(776768K) (in the first line)

是总可用空间,不计算永久代中的空间,这是总堆减去幸存者空间之一。次要收藏大约花费了四分之一秒。

0.2300771 secs (in the first line)

有关更多信息,请参见:http : //java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html


17

这里

    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
关于记忆?
Daniel DeLeón2013年

2
List <MemoryPoolMXBean> memoryPools =新的ArrayList <MemoryPoolMXBean>(ManagementFactory.getMemoryPoolMXBeans()); 长时间使用HeapMemoryAfterLastGC = 0; 对于(MemoryPoolMXBean memoryPool:memoryPools){如果((memoryPool.getType()。equals(MemoryType.HEAP)){内存使用情况 usedHeapMemoryAfterLastGC + = poolCollectionMemoryUsage.getUsed(); }}
danieln

1
感谢您提供显示CPU使用率检索的唯一答案。
马修(Matthieu)

1
做这个和简单做之间有什么区别operatingSystemMXBean.getProcessCpuLoad();?根据Oracle文档,此方法返回“返回Java虚拟机进程的”最近的cpu使用情况”。但是,我发现您的方法与该方法之间存在较大的差异。
Ishnark

1
@RobHall有两个OperatingSystemMXBean类。一种是中提供的接口java.lang。但是还有另一个版本,在中扩展了该版本com.sun.management。那就是我所指的方法OperatingSystemMXBean
-Ishnark

9

JMX,所提供的MXBean(ThreadMXBean等)将为您提供内存和CPU使用率。

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

8

对于内存使用,以下方法将起作用,

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

对于CPU使用率,您需要使用外部应用程序进行测量。


5

从Java 1.5开始,JDK附带了一个新工具:JConsole wich可以向您显示任何1.5或更高版本JVM的CPU和内存使用情况。它可以绘制这些参数的图表,导出为CSV,显示加载的类数,实例数,死锁,线程等。


4

如果您使用此处很多答案中都已发布的运行时/ totalMemory解决方案(我已经做了很多),如果您想要相当准确/一致的结果,请务必先强制执行两个垃圾回收。

为了提高效率,Java通常允许垃圾在强制使用GC之前先填满所有内存,即使这样,它通常也不是完整的GC,因此,runtime.freeMemory()的结果始终在“实际”可用内存量和0之间。 。

第一个GC不能得到所有,它可以得到大部分。

向上发展的是,如果您仅执行freeMemory()调用,您将获得一个绝对没有用的数字,并且数值相差很大,但是如果首先执行2 gc,这将是一个非常可靠的指标。这也使例行MUCH变慢(可能是几秒钟)。


3

Java的Runtime对象可以报告JVM的内存使用情况。对于CPU消耗,您必须使用外部实用程序,例如Unix的top或Windows Process Manager。


2

这是一些简单的代码,用于计算当前的内存使用量(以兆字节为单位):

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

2

我还将添加以下跟踪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();
}

你可以在这里阅读更多





By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.