我需要检查java中服务器的CPU和内存使用情况,有人知道怎么做吗?
16 回答
如果您正在专门寻找 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/>");
但是,这些仅应作为估计...
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();
}
}
如果您使用的是 Sun JVM,并且对应用程序的内部内存使用情况(您的应用程序正在使用的分配内存有多少)感兴趣,我更喜欢打开 JVM 内置的垃圾收集日志记录。您只需将 -verbose:gc 添加到启动命令中。
从太阳文档:
命令行参数 -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
从这里
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);
JMX, The MXBeans (ThreadMXBean, etc) provided will give you Memory and CPU usages.
OperatingSystemMXBean operatingSystemMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
operatingSystemMXBean.getSystemCpuLoad();
对于内存使用,以下将起作用,
long total = Runtime.getRuntime().totalMemory();
long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
对于 CPU 使用率,您需要使用外部应用程序来测量它。
从 Java 1.5 开始,JDK 附带了一个新工具:JConsole,它可以显示任何 1.5 或更高版本 JVM 的 CPU 和内存使用情况。它可以制作这些参数的图表,导出为 CSV,显示加载的类数、实例数、死锁、线程等......
如果您使用已在此处发布的许多答案中发布的运行时/总内存解决方案(我已经做了很多),如果您想要相当准确/一致的结果,请务必先强制进行两次垃圾收集。
为了提高效率,Java 通常允许垃圾在强制 GC 之前填满所有内存,即使那样它通常也不是完整的 GC,因此 runtime.freeMemory() 的结果总是介于“实际”可用内存量和 0 之间.
第一次 GC 并没有得到所有东西,它得到了大部分。
好处是,如果你只是调用 freeMemory(),你会得到一个绝对没用的数字,而且变化很大,但如果先做 2 gc,它是一个非常可靠的指标。它还使例程变得更慢(可能是几秒钟)。
Java 的Runtime对象可以报告 JVM 的内存使用情况。对于 CPU 消耗,您必须使用外部实用程序,例如 Unix 的顶级或 Windows 进程管理器。
JConsole是一种监视正在运行的 Java 应用程序的简单方法,或者您可以使用 Profiler 来获取有关您的应用程序的更多详细信息。我喜欢为此使用NetBeans Profiler。
下面是一些简单的代码来计算当前内存使用量(以 MB 为单位):
double currentMemory = ( (double)((double)(Runtime.getRuntime().totalMemory()/1024)/1024))- ((double)((double)(Runtime.getRuntime().freeMemory()/1024)/1024));
我还将添加以下方法来跟踪 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();
}
你可以在这里阅读更多
如果您使用的是 Tomcat,请查看Psi Probe,它可以让您监控内部和外部内存消耗以及许多其他区域。
The YourKit Java profiler is an excellent commercial solution. You can find further information in the docs on CPU profiling and memory profiling.
对于 Eclipse,您可以使用 TPTP(测试和性能工具平台)来分析内存使用情况等更多信息
我想在现有答案中添加注释:
这些方法只跟踪 JVM 内存。实际进程可能会消耗更多内存。
java.nio.ByteBuffer.allocateDirect() 是一个函数/库,很容易错过,并且确实分配了本机内存,这不是 Java 内存管理的一部分。
在 Linux 上,您可以使用类似的方法来获取实际消耗的内存:https ://linuxhint.com/check_memory_usage_process_linux/