Vra

Ek is tans besig om 'n Java program wat kan beland wat uitgevoer word op baie verskillende platforms, maar in die eerste plek variante van Solaris, Linux en Windows.

Het iemand in staat om suksesvol inligting te onttrek nie, soos die huidige skyfspasie gebruik, CPU gebruik en geheue gebruik in die onderliggende bedryfstelsel? Wat van presies wat die Java jeug self is in beslag?

verkieslik Ek wil graag hierdie inligting te kry sonder die gebruik van JNI.

Was dit nuttig?

Oplossing

Jy kan 'n paar beperkte geheue inligting uit die Runtime klas kry. Dit is regtig nie presies wat jy is op soek na, maar ek het gedink ek sou dit gee ter wille van volledigheid. Hier is 'n klein voorbeeld. Edit: Jy kan ook skyf gebruik inligting uit die java.io.File klas. Die spasie op die hardeskyf gebruik dinge vereis Java 1.6 of hoër.

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());
    }
  }
}

Ander wenke

Die java.lang.management pakket gee jou 'n hele klomp meer inligting as Runtime -. byvoorbeeld dit aan julle gee ophoop geheue (ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()) skei van nie-hoop geheue (ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage())

Jy kan ook proses CPU gebruik (sonder die skryf van jou eie JNI kode), maar wat jy nodig het om die java.lang.management.OperatingSystemMXBean werp om 'n com.sun.management.OperatingSystemMXBean. Dit werk op Windows en Linux, ek het nie dit elders getoets.

Byvoorbeeld ... noem die metode kry getCpuUsage () meer dikwels om meer akkurate lesings kry.

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();
        }
    }
}

Ek dink die beste metode daar buite is om die SIGAR API deur Hyperic implementeer. Dit werk vir die meeste van die groot bedryfstelsels (darn naby enigiets moderne) en is baie maklik om mee te werk. Die ontwikkelaar (s) is baie gevoelig op hul forum en poslyste. Ek hou ook dat dit GPL2 Apache lisensie . Hulle bied 'n ton van voorbeelde in Java te!

SIGAR == System Information, versamel en verslagdoening hulpmiddel.

Daar is 'n Java projek wat JNA gebruik (sodat daar geen inheemse biblioteke te installeer) en is in aktiewe ontwikkeling. Dit ondersteun tans Linux, OSX, Windows, Solaris en FreeBSD en bied RAM, CPU, battery en lêer stelsel inligting.

Jy kan 'n paar stelsel-vlak inligting deur gebruik te maak van System.getenv(), verby die betrokke omgewing veranderlike naam as 'n parameter te kry. Byvoorbeeld, op Windows:

System.getenv("PROCESSOR_IDENTIFIER")
System.getenv("PROCESSOR_ARCHITECTURE")
System.getenv("PROCESSOR_ARCHITEW6432")
System.getenv("NUMBER_OF_PROCESSORS")

Vir ander bedryfstelsels die teenwoordigheid / afwesigheid en name van die betrokke omgewing veranderlikes sal verskil.

Vir vensters Ek het op hierdie manier.

    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();

Hier is die skakel met besonderhede.

Voeg OSHI afhanklikheid via Maven:

<dependency>
    <groupId>com.github.dblock</groupId>
    <artifactId>oshi-core</artifactId>
    <version>2.2</version>
</dependency>

Kry 'n battery kapasiteit links in persentasie:

SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();
for (PowerSource pSource : hal.getPowerSources()) {
    System.out.println(String.format("%n %s @ %.1f%%", pSource.getName(), pSource.getRemainingCapacity() * 100d));
}

Het jy 'n blik op die API's beskikbaar in die java.lang.management pakket. Byvoorbeeld:

  • OperatingSystemMXBean.getSystemLoadAverage()
  • ThreadMXBean.getCurrentThreadCpuTime()
  • ThreadMXBean.getCurrentThreadUserTime()

Daar is baie ander nuttige dinge in daar so goed.

Gewoonlik, na 'n lae vlak OS inligting te kry wat jy kan OS spesifieke opdragte waarin jy die inligting wat jy wil met Runtime.exec (gee noem) of lees lêers soos / proc / * in Linux.

CPU gebruik is nie eenvoudig - java.lang.management via com.sun.management.OperatingSystemMXBean.getProcessCpuTime kom naby (sien Patrick se uitstekende kode uit bo), maar daarop dat dit slegs toegang tot tyd die CPU spandeer in gee jou proses. dit sal nie vir jou oor CPU tyd nodig vir ander prosesse, of selfs CPU tyd spandeer doen stelsel aktiwiteite wat verband hou met jou proses.

byvoorbeeld ek het 'n netwerk-intensiewe java proses - dit is die enigste ding wat hardloop en die CPU is op 99%, maar slegs 55% van wat berig as "verwerker CPU"

.

kry nie eens my op "load gemiddelde" begin as dit is langs nutteloos, ten spyte daarvan dat die enigste cpu verwante item op die MX boontjie. al is dit net son in hul af en wysheid blootgestel iets soos "getTotalCpuTime" ...

vir ernstige deur Matt genoem CPU monitering SIGAR lyk die beste bet.

Dit is nog onder ontwikkeling, maar jy kan reeds gebruik jHardware

Dit is 'n eenvoudige biblioteek wat stukkies stelsel data met behulp van Java. Dit werk in beide Linux en 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());
//[...]

As jy 'Jrockit VM dan hier is 'n ander manier om VM CPU gebruik. Runtime boontjie kan ook vir jou CPU load per verwerker. Ek het hierdie gebruik net op Red Hat Linux te waarnemer Tomcat prestasie. Jy moet JMX remote in staat te stel in catalina.sh vir hierdie om te werk.

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");

Op Windows, kan jy die systeminfo opdrag uit te voer en gekry sy produksie byvoorbeeld met die volgende kode:

private static class WindowsSystemInformation
{
    static String get() throws IOException
    {
        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec("systeminfo");
        BufferedReader systemInformationReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

        StringBuilder stringBuilder = new StringBuilder();
        String line;

        while ((line = systemInformationReader.readLine()) != null)
        {
            stringBuilder.append(line);
            stringBuilder.append(System.lineSeparator());
        }

        return stringBuilder.toString().trim();
    }
}

Een eenvoudige manier wat gebruik kan word om die bedryfstelsel vlak inligting te kry en ek getoets in my Mac wat goed werk:

 OperatingSystemMXBean osBean =
        (OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
    return osBean.getProcessCpuLoad();

Jy kan baie relevante statistieke van die bedryfstelsel hier

Hey jy kan dit doen met Java / com integrasie. Deur toegang tot WMI eienskappe wat jy kan al die inligting te kry.

scroll top