私は現在、多くの異なるプラットフォームで実行される可能性のあるJavaアプリを構築していますが、主にSolaris、Linux、およびWindowsのバリアントです。
現在使用されているディスク容量、CPU使用率、基盤となるOSで使用されているメモリなどの情報を正常に抽出できた人はいますか?Javaアプリ自体が消費しているものはどうですか?
できれば、JNIを使用せずにこの情報を取得したいと思います。
ランタイム クラスから制限されたメモリ情報を取得できます。それはあなたが探しているものとはまったく異なりますが、完全を期すために提供したいと思います。ここに小さな例があります。編集: java.io.File クラスからディスク使用情報を取得することもできます。ディスク容量の使用には、Java 1.6 以降が必要です。
public class Main {
public static void main(String[] args) {
/* Total number of processors or cores available to the JVM */
System.out.println("Available processors (cores): " +
Runtime.getRuntime().availableProcessors());
/* Total amount of free memory available to the JVM */
System.out.println("Free memory (bytes): " +
Runtime.getRuntime().freeMemory());
/* This will return Long.MAX_VALUE if there is no preset limit */
long maxMemory = Runtime.getRuntime().maxMemory();
/* Maximum amount of memory the JVM will attempt to use */
System.out.println("Maximum memory (bytes): " +
(maxMemory == Long.MAX_VALUE ? "no limit" : maxMemory));
/* Total memory currently available to the JVM */
System.out.println("Total memory available to JVM (bytes): " +
Runtime.getRuntime().totalMemory());
/* Get a list of all filesystem roots on this system */
File[] roots = File.listRoots();
/* For each filesystem root, print some info */
for (File root : roots) {
System.out.println("File system root: " + root.getAbsolutePath());
System.out.println("Total space (bytes): " + root.getTotalSpace());
System.out.println("Free space (bytes): " + root.getFreeSpace());
System.out.println("Usable space (bytes): " + root.getUsableSpace());
}
}
}
java.lang.managementパッケージは、Runtime よりもはるかに多くの情報を提供します。たとえば、非ヒープ メモリ ( )ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()
とは別にヒープ メモリ ( ) を提供しますManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage()
。
プロセスの CPU 使用率を (独自の JNI コードを記述せずに) 取得することもできますが、 を にキャストする必要がありjava.lang.management.OperatingSystemMXBean
ますcom.sun.management.OperatingSystemMXBean
。これは Windows と Linux で動作しますが、他の場所ではテストしていません。
たとえば ... get getCpuUsage() メソッドをより頻繁に呼び出して、より正確な読み取り値を取得します。
public class PerformanceMonitor {
private int availableProcessors = getOperatingSystemMXBean().getAvailableProcessors();
private long lastSystemTime = 0;
private long lastProcessCpuTime = 0;
public synchronized double getCpuUsage()
{
if ( lastSystemTime == 0 )
{
baselineCounters();
return;
}
long systemTime = System.nanoTime();
long processCpuTime = 0;
if ( getOperatingSystemMXBean() instanceof OperatingSystemMXBean )
{
processCpuTime = ( (OperatingSystemMXBean) getOperatingSystemMXBean() ).getProcessCpuTime();
}
double cpuUsage = (double) ( processCpuTime - lastProcessCpuTime ) / ( systemTime - lastSystemTime );
lastSystemTime = systemTime;
lastProcessCpuTime = processCpuTime;
return cpuUsage / availableProcessors;
}
private void baselineCounters()
{
lastSystemTime = System.nanoTime();
if ( getOperatingSystemMXBean() instanceof OperatingSystemMXBean )
{
lastProcessCpuTime = ( (OperatingSystemMXBean) getOperatingSystemMXBean() ).getProcessCpuTime();
}
}
}
Hyperic でSIGAR APIを実装するのが最善の方法だと思います。これは、ほとんどの主要なオペレーティング システム (最新のものに近いもの) で動作し、操作が非常に簡単です。開発者は、フォーラムやメーリング リストで非常に反応が良いです。また、 GPL2 Apache ライセンスであることも気に入っています。彼らはJavaでもたくさんの例を提供しています!
JNA を使用する Java プロジェクトがあり (ネイティブ ライブラリをインストールする必要はありません)、開発が活発に行われています。現在、Linux、OSX、Windows、Solaris、および FreeBSD をサポートしており、RAM、CPU、バッテリー、およびファイル システムの情報を提供します。
Windowsの場合、私はこのように行きました。
com.sun.management.OperatingSystemMXBean os = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
long physicalMemorySize = os.getTotalPhysicalMemorySize();
long freePhysicalMemory = os.getFreePhysicalMemorySize();
long freeSwapSize = os.getFreeSwapSpaceSize();
long commitedVirtualMemorySize = os.getCommittedVirtualMemorySize();
詳細のリンクはこちらです。
System.getenv()
を使用して、関連する環境変数名をパラメーターとして渡すことにより、システムレベルの情報を取得できます。たとえば、Windows では次のようになります。
System.getenv("PROCESSOR_IDENTIFIER")
System.getenv("PROCESSOR_ARCHITECTURE")
System.getenv("PROCESSOR_ARCHITEW6432")
System.getenv("NUMBER_OF_PROCESSORS")
他のオペレーティング システムでは、関連する環境変数の有無と名前が異なります。
java.lang.managementパッケージで利用可能な API を見てください。例えば:
OperatingSystemMXBean.getSystemLoadAverage()
ThreadMXBean.getCurrentThreadCpuTime()
ThreadMXBean.getCurrentThreadUserTime()
他にも便利なものがたくさんあります。
CPU使用率は単純ではありません-com.sun.management.OperatingSystemMXBean.getProcessCpuTimeを介したjava.lang.managementが近づいています(上記のPatrickの優れたコードスニペットを参照)が、CPUがプロセスに費やした時間へのアクセスのみを提供することに注意してください。他のプロセスで費やされたCPU時間、またはプロセスに関連するシステムアクティビティの実行に費やされたCPU時間についてはわかりません。
たとえば、ネットワークを集中的に使用するJavaプロセスがあります。実行中のJavaプロセスはこれだけで、CPUは99%ですが、「プロセッサCPU」として報告されるのはその55%だけです。
MX Beanで唯一のCPU関連のアイテムであるにもかかわらず、「負荷平均」はほとんど役に立たないので、始めないでください。彼らの時折の知恵の太陽だけが「getTotalCpuTime」のような何かを暴露したなら...
深刻なCPUモニタリングについては、Mattが言及したSIGARが最善の策のようです。
まだ開発中ですが、すでにjHardwareを使用できます
Javaを使ってシステムデータをスクラップするシンプルなライブラリです。Linux と Windows の両方で動作します。
ProcessorInfo info = HardwareInfo.getProcessorInfo();
//Get named info
System.out.println("Cache size: " + info.getCacheSize());
System.out.println("Family: " + info.getFamily());
System.out.println("Speed (Mhz): " + info.getMhz());
//[...]
Jrockit VM を使用している場合は、VM の CPU 使用率を取得する別の方法があります。ランタイム Bean は、プロセッサごとの CPU 負荷も与えることができます。これは、Tomcat のパフォーマンスを観察するために Red Hat Linux でのみ使用しました。これを機能させるには、catalina.sh で JMX リモートを有効にする必要があります。
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://my.tomcat.host:8080/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection conn = jmxc.getMBeanServerConnection();
ObjectName name = new ObjectName("oracle.jrockit.management:type=Runtime");
Double jvmCpuLoad =(Double)conn.getAttribute(name, "VMGeneratedCPULoad");