Linux java system load

How do I monitor the computer’s CPU, memory, and disk usage in Java?

I’m looking for a cross-platform solution (Linux, Mac, and Windows) that doesn’t rely on my own code calling external programs or using JNI. Although these are viable options, I would prefer not to maintain OS-specific code myself if someone already has a better solution.

If there’s a free library out there that does this in a reliable, cross-platform manner, that would be great (even if it makes external calls or uses native code itself).

Any suggestions are much appreciated.

To clarify, I would like to get the current CPU usage for the whole system, not just the Java process(es).

The SIGAR API provides all the functionality I’m looking for in one package, so it’s the best answer to my question so far. However, due it being licensed under the GPL, I cannot use it for my original purpose (a closed source, commercial product). It’s possible that Hyperic may license SIGAR for commercial use, but I haven’t looked into it. For my GPL projects, I will definitely consider SIGAR in the future.

For my current needs, I’m leaning towards the following:

  • For CPU usage, OperatingSystemMXBean.getSystemLoadAverage() / OperatingSystemMXBean.getAvailableProcessors() (load average per cpu)
  • For memory, OperatingSystemMXBean.getTotalPhysicalMemorySize() and OperatingSystemMXBean.getFreePhysicalMemorySize()
  • For disk space, File.getTotalSpace() and File.getUsableSpace()

The getSystemLoadAverage() and disk space querying methods are only available under Java 6. Also, some JMX functionality may not be available to all platforms (i.e. it’s been reported that getSystemLoadAverage() returns -1 on Windows).

Although originally licensed under GPL, it has been changed to Apache 2.0, which can generally be used for closed source, commercial products.

SIGAR being under the GPL does not preclude you from using it, it just means you have to contact the authors and request alternate licensing. Authors are often happy to accept a small fee and allow commercial licensing.

12 Answers 12

Along the lines of what I mentioned in this post. I recommend you use the SIGAR API. I use the SIGAR API in one of my own applications and it is great. You’ll find it is stable, well supported, and full of useful examples. It is open-source with a GPL 2 Apache 2.0 license. Check it out. I have a feeling it will meet your needs.

Using Java and the Sigar API you can get Memory, CPU, Disk, Load-Average, Network Interface info and metrics, Process Table information, Route info, etc.

Be careful when using Sigar, there are problems on x64 machines. stackoverflow.com/questions/23405832/… and it seems the library doesn’t get updated since 2010

The following supposedly gets you CPU and RAM. See ManagementFactory for more details.

import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.lang.reflect.Method; import java.lang.reflect.Modifier; private static void printUsage() < OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean(); for (Method method : operatingSystemMXBean.getClass().getDeclaredMethods()) < method.setAccessible(true); if (method.getName().startsWith("get") && Modifier.isPublic(method.getModifiers())) < Object value; try < value = method.invoke(operatingSystemMXBean); >catch (Exception e) < value = e; >// try System.out.println(method.getName() + " mt24">
)" data-controller="se-share-sheet" data-se-share-sheet-title="Share a link to this answer" data-se-share-sheet-subtitle="" data-se-share-sheet-post-type="answer" data-se-share-sheet-social="facebook twitter devto" data-se-share-sheet-location="2" data-se-share-sheet-license-url="https%3a%2f%2fcreativecommons.org%2flicenses%2fby-sa%2f3.0%2f" data-se-share-sheet-license-name="CC BY-SA 3.0" data-s-popover-placement="bottom-start">Share
)" title="">Improve this answer
)">edited Aug 9, 2017 at 10:05
Peter Mortensen
30.8k21 gold badges105 silver badges131 bronze badges
answered Sep 6, 2008 at 2:23
5
    3
    Sample output for the code above. This code does work on Java 1.5. getCommittedVirtualMemorySize = 28622848 getFreePhysicalMemorySize = 228462592 getFreeSwapSpaceSize = 1129848832 getProcessCpuTime = 390625000 getTotalPhysicalMemorySize = 2147483647 getTotalSwapSpaceSize = 4294967295
    – blak3r
    May 20, 2009 at 5:41
    AFAIK getProcessCpuTime = 390625000 is only how long that thread has been running. That is not really useful for determining the processor usage
    – MikeNereson
    Jul 14, 2009 at 15:35
    2
    Not sure it's actually reliable. On Windows XP with 4GB of physical memory it only reports 2GB (tested with Java 6 and Java 7). The total swap size is also wrong.
    – Emmanuel Bourg
    Jul 28, 2011 at 17:59
    4
    @EmmanuelBourg just to document for people who see this topic, there's a bug related to this.
    user800014
    Sep 13, 2012 at 17:22
    3
    This method worked great until Java 9, it now throws a java.lang.reflect.InaccessibleObjectException due to the new access checking framework Java is using.
    – Thor Lancaster
    Jul 26, 2019 at 0:14
Add a comment|
48

In JDK 1.7, you can get system CPU and memory usage via com.sun.management.OperatingSystemMXBean. This is different than java.lang.management.OperatingSystemMXBean.

long getCommittedVirtualMemorySize() // Returns the amount of virtual memory that is guaranteed to be available to the running process in bytes, or -1 if this operation is not supported. long getFreePhysicalMemorySize() // Returns the amount of free physical memory in bytes. long getFreeSwapSpaceSize() // Returns the amount of free swap space in bytes. double getProcessCpuLoad() // Returns the "recent cpu usage" for the Java Virtual Machine process. long getProcessCpuTime() // Returns the CPU time used by the process on which the Java virtual machine is running in nanoseconds. double getSystemCpuLoad() // Returns the "recent cpu usage" for the whole system. long getTotalPhysicalMemorySize() // Returns the total amount of physical memory in bytes. long getTotalSwapSpaceSize() // Returns the total amount of swap space in bytes.

Источник

how to get cpu load linux java in percent precise and easy way?

The CPU percentage is then the relative cpu time between the last and the current second divided by the timestamp difference. Here's a simple example implementation of a CpuStats Class:

public class CpuStats < private final long threadId; private long lastCpuTime = 0; private long lastPoll = 0; /** * Creates a CpuStats object for a single thread. * @param threadId The id of the thread to monitor * */ public CpuStats (long threadId) < this.threadId = threadId; lastCpuTime = getTotalTime (); lastPoll = System.nanoTime (); >/** * Creates a CpuStatus object for all threads. The supplied statistics affect * all threads in the current VM. */ public CpuStats () < threadId = -1; lastCpuTime = getTotalTime (); lastPoll = System.nanoTime (); >private long getRelativeTime () < long currentCpuTime = getTotalTime (); long ret = currentCpuTime - lastCpuTime; lastCpuTime = currentCpuTime; return ret; >public double getUsage () < long timeBefore = this.lastPoll; lastPoll = System.nanoTime (); long relTime = getRelativeTime (); return Math.max ((double)relTime / (double)(lastPoll - timeBefore), 0.0); >private long getTotalTime () < if (threadId == -1) < long cpuTime = 0; for (long id : ManagementFactory.getThreadMXBean ().getAllThreadIds ()) < cpuTime += ManagementFactory.getThreadMXBean ().getThreadCpuTime (id); >return cpuTime; > else < return ManagementFactory.getThreadMXBean ().getThreadCpuTime (threadId); >> > 

Источник

CPU load from Java

getSystemLoadAverage() gives you value over 1 minute of time (refreshes every second) and gives this value for overall operating system. More realtime overview should be done by monitoring each thread separately. Important is also notice the monitoring refresh interval - more often you check the value, more precice it is in given moment and if you do it every millisecond, it is typically 0 or 100 (or more depending how many CPU's is there). But if we allow timeframe (for example 1 second), we get avarage over this period of time and we get more informative result. Also, it is important to notice, that it is highly unlikely, that only one thread occupies more than one CPU (core).

Following implementation allows to use 3 methods:

  • getTotalUsage() - Total load by all the threads in JVM
  • getAvarageUsagePerCPU() - Avarage load per CPU (core)
  • getUsageByThread(Thread t) - Total load by specified thread
import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.lang.management.ThreadMXBean; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; public class MonitoringThread extends Thread < private long refreshInterval; private boolean stopped; private MapthreadTimeMap = new HashMap(); private ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); private OperatingSystemMXBean opBean = ManagementFactory.getOperatingSystemMXBean(); public MonitoringThread(long refreshInterval) < this.refreshInterval = refreshInterval; setName("MonitoringThread"); start(); >@Override public void run() < while(!stopped) < SetmappedIds; synchronized (threadTimeMap) < mappedIds = new HashSet(threadTimeMap.keySet()); > long[] allThreadIds = threadBean.getAllThreadIds(); removeDeadThreads(mappedIds, allThreadIds); mapNewThreads(allThreadIds); Collection values; synchronized (threadTimeMap) < values = new HashSet(threadTimeMap.values()); > for (ThreadTime threadTime : values) < synchronized (threadTime) < threadTime.setCurrent(threadBean.getThreadCpuTime(threadTime.getId())); >> try < Thread.sleep(refreshInterval); >catch (InterruptedException e) < throw new RuntimeException(e); >for (ThreadTime threadTime : values) < synchronized (threadTime) < threadTime.setLast(threadTime.getCurrent()); >> > > private void mapNewThreads(long[] allThreadIds) < for (long id : allThreadIds) < synchronized (threadTimeMap) < if(!threadTimeMap.containsKey(id)) threadTimeMap.put(id, new ThreadTime(id)); >> > private void removeDeadThreads(Set mappedIds, long[] allThreadIds) < outer: for (long id1 : mappedIds) < for (long id2 : allThreadIds) < if(id1 == id2) continue outer; >synchronized (threadTimeMap) < threadTimeMap.remove(id1); >> > public void stopMonitor() < this.stopped = true; >public double getTotalUsage() < Collectionvalues; synchronized (threadTimeMap) < values = new HashSet(threadTimeMap.values()); > double usage = 0D; for (ThreadTime threadTime : values) < synchronized (threadTime) < usage += (threadTime.getCurrent() - threadTime.getLast()) / (refreshInterval * 10000); >> return usage; > public double getAvarageUsagePerCPU() < return getTotalUsage() / opBean.getAvailableProcessors(); >public double getUsageByThread(Thread t) < ThreadTime info; synchronized (threadTimeMap) < info = threadTimeMap.get(t.getId()); >double usage = 0D; if(info != null) < synchronized (info) < usage = (info.getCurrent() - info.getLast()) / (refreshInterval * 10000); >> return usage; > static class ThreadTime < private long id; private long last; private long current; public ThreadTime(long id) < this.id = id; >public long getId() < return id; >public long getLast() < return last; >public void setLast(long last) < this.last = last; >public long getCurrent() < return current; >public void setCurrent(long current) < this.current = current; >> > 

Источник

java cpu usage monitoring

There is a gem in the comments on the article which kgiannakakis linked:

JavaSysMon manages processes and reports useful system performance metrics cross-platform. You can think of it as a cross-platform version of the UNIX `top’ command, along with the ability to kill processes. It comes in the form of a single JAR file /..

-works on Windows, Mac OS X, Linux, and Solaris.

How about using jmx mbeans?

final OperatingSystemMXBean myOsBean= ManagementFactory.getOperatingSystemMXBean(); double load = myOsBean.getSystemLoadAverage(); 

docs says -1 means not supported. But on linux I get value less than what OS says, so I assume it is the CPU load used by current JVM?

You can use jMX beans to calculate a CPU load. Note that this measures CPU load of your java program, not the overall system load. (the question didn't specify which)

 ThreadMXBean newBean = ManagementFactory.getThreadMXBean(); try < if (this.newBean.isThreadCpuTimeSupported()) this.newBean.setThreadCpuTimeEnabled(true); else throw new AccessControlException(""); >catch (AccessControlException e)

Then as your loop (assuming your application uses a loop, otherwise what's the point in measuring CPU usage?) use this:

 long lastTime = System.nanoTime(); long lastThreadTime = newBean.getCurrentThreadCpuTime(); while (true) < // Do something that takes at least 10ms (on windows) try < int j = 0; for (int i = 0; i < 20000000; i++) j = (j + i) * j / 2; Thread.sleep(100); >catch (InterruptedException e) < >// Calculate coarse CPU usage: long time = System.nanoTime(); long threadTime = newBean.getCurrentThreadCpuTime(); double load = (threadTime - lastThreadTime) / (double)(time - lastTime); System.out.println((float)load); // For next iteration. lastTime = time; lastThreadTime = threadTime; > 

You need to use double precision because a long doesn't fit in a float (though it might work 99.9999999999999999% of the time)

If the 'something' you're doing takes less than approximately 1.6ms (Windows), then the returned value will not even have increased at all and you'll perpetually measure 0% CPU erroneously.

Because getCurrentThreadCpuTime is VERY inaccurate (with delays less than 100ms), smoothing it helps a lot:

 long lastTime = System.nanoTime(); long lastThreadTime = newBean.getCurrentThreadCpuTime(); float smoothLoad = 0; while (true) < // Do something that takes at least 10ms (on windows) try < int j = 0; for (int i = 0; i < 2000000; i++) j = (j + i) * j / 2; Thread.sleep(10); >catch (InterruptedException e) < >// Calculate coarse CPU usage: long time = System.nanoTime(); long threadTime = newBean.getCurrentThreadCpuTime(); double load = (threadTime - lastThreadTime) / (double)(time - lastTime); // Smooth it. smoothLoad += (load - smoothLoad) * 0.1; // damping factor, lower means less responsive, 1 means no smoothing. System.out.println(smoothLoad); // For next iteration. lastTime = time; lastThreadTime = threadTime; > 

Источник

How to get percentage of CPU usage of OS from java

But it gives the cpu load but not the cpu usage. Is there anyway to find the usage percentage?

Can you link to Javadoc for the OperatingSystemMXBean please? Is percentage calculated from load or vice versa? I do not know, but it might be.

2 Answers 2

In Java 7 you can get it like so:

public static double getProcessCpuLoad() throws Exception < MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); ObjectName name = ObjectName.getInstance("java.lang:type=OperatingSystem"); AttributeList list = mbs.getAttributes(name, new String[]< "ProcessCpuLoad" >); if (list.isEmpty()) return Double.NaN; Attribute att = (Attribute)list.get(0); Double value = (Double)att.getValue(); // usually takes a couple of seconds before we get real values if (value == -1.0) return Double.NaN; // returns a percentage value with 1 decimal point precision return ((int)(value * 1000) / 10.0); > 

Does this only work on certain operating systems? Running Java 7u15 on 64bit Windows 7, NaN is returned, as value is negative one.

It should work on all. I tested it on Window 7 Java7u51 64bit and it works fine after a few seconds. The first few seconds return -1.0 because it takes some time to initialize some of the objects/values.

Interesting, it seems to take about one second on my machine for the CPU load to be an actual value. Thanks for the clarification. +1

ProcessCpuLoad is the % CPU load of that JVM for the system. there is also SystemCpuLoad which gives the load of the whole system. did you try to call it in a loop? I noticed that the first few calls return -1.0

Источник

Читайте также:  Linux android usb internet
Оцените статью
Adblock
detector