Would like this feature but don't know C

47 views
Skip to first unread message

Baron Von Awsm

unread,
Nov 19, 2012, 7:02:57 PM11/19/12
to javas...@googlegroups.com
I have two requirements for my Java code running on Windows and Linux.
 
1. At a moment in time, read the current percentage of memory capacity is use.
 
2. At a moment in time, read the current percentage of CPU capacity is use.
 
Using javasysmon 0.3.3, I am able to do #1. I could not find a way to do #2, CPU usage. The API's current total, user, system and idle CPU time do not help me calculate the current percentage of CPU capacity in use at a moment in time.
 
Have I overlooked something? Does the API already provide a way to do what I want?
 
Working on the assumption that the capability is currently not in the API, is there anyone involved in the project who can do the C coding to support this feature? I have Java knowledge but not C knowledge.
 
Cheers,
Baron

Jez Humble

unread,
Nov 19, 2012, 7:51:11 PM11/19/12
to javas...@googlegroups.com
Hey there.

You can do this. Go to the JavaDoc that's linked to from the README: http://jezhumble.github.com/javasysmon/

Go to the Monitor interface. You'll see a method called cpuTimes. Follow the link and read the description.

Thanks,

Jez.

Baron Von Awsm

unread,
Nov 19, 2012, 9:16:35 PM11/19/12
to javas...@googlegroups.com
Hi Jez
 
Thanks for your reply.
 
Prior to posting, I did take a very good look at the JavaDocs and did some code to get an idea of what CpuTimes exposes. To me, it does not appear to give me the information I need. Here's my understanding of things, please correct me if/where I'm getting it wrong.
 
CpuTimes tells you whether the cpu was idle or active. Via getCpuUsage(...) you can determine the percentage of time the cpu was idle or active over a period of time.
 
But this is not what I am trying to determine. I am not trying to determine the percentage of time the cpu was active. I am trying to determine, at a moment in time, how active the cpu is, as a percentage. I would like to understand, at a moment in time, what percentage of cpu capacity is in use. For instance, I can open system monitor on windows and see my cpu usage is currently 20% (see attached screenshot).
 
Am I misunderstanding? Is this information already there and I'm simply not seeing how to get it out of the API?
 
Here's the code I put together in an attempt to determine memory and cpu usage,

 private static void testJavaSysMon() {
 
      displayMemoryUsage();
      displayCpuUsage();
 
      return;
 }
 
 private static void displayMemoryUsage() {
 
      JavaSysMon systemMonitor = null;
      MemoryStats memoryUsage = null;
      int figure = 0;
 
      systemMonitor = new JavaSysMon();
      memoryUsage = systemMonitor.physical();
 
      figure = (int)Math.ceil(
           100 * ((double)(memoryUsage.getTotalBytes() - memoryUsage.getFreeBytes()) / memoryUsage.getTotalBytes()));
 
      logger.debug("Memory Usage: " + figure);
 
      return;
 }
 
 private static void displayCpuUsage() {
 
      JavaSysMon systemMonitor = null;
      CpuTimes cpuTimes = null;
      int figure = 0;
 
      systemMonitor = new JavaSysMon();
      cpuTimes = systemMonitor.cpuTimes();
 
      Methods.sleep(10000);
 
      figure = (int)Math.ceil(100 * cpuTimes.getCpuUsage(cpuTimes));
 
      logger.debug("CPU Usage: " + figure);
 
      return;
 }
 
 
Here is the output of running the code,
 
Memory Usage: 66
CPU Usage: 100
 
The output for memory is correct and what I want. The output for cpu usage is not what I want. The data for cpu usage is based simply on whether the cpu was active or idle during the period and, in this case, the output is reporting that the cpu was always active in the period. But I just don't want to know if it was active, I want to know how active, as a percentage of total cpu capacity, the cpu was in a moment in time - just like my Windows resource monitor shows me.
 
Would appreciate any feedback you can give me.
 
Cheers,
Baron.
CpuUsage.png

Jez Humble

unread,
Nov 19, 2012, 9:43:18 PM11/19/12
to javas...@googlegroups.com
Here's the deal. The CPU is always executing instructions*. So there's no such thing as an "instantaneous" CPU usage. But the operating system records how much time time the CPU is executing kernel tasks, userland tasks, and the total time it's been running.

So here's what the Windows resource monitor does. It takes a snapshot every second, and then looks at what has changed in the intervening second. So that's what you do with JavaSysMon too.

 systemMonitor = new JavaSysMon();
 cpuTimes = systemMonitor.cpuTimes();
 Methods.sleep(10000);
 usage = systemMonitor.cpuTimes().getCpuUsage(cpuTimes); // Calculate the proportion of the last second that has been spent doing stuff. usage is a float. See getCpuUsage JavaDoc for more details.

Of course you wouldn't just sleep in real life, you'd set up a thread to poll every 10 seconds or so (depending on how much of the CPU time you want your monitoring to suck up) to grab the current totals and calculate the delta using the getCpuUsage method.

Thanks,

Jez.

* When the CPU is "idle" it's still executing instructions, it's just that the OS is doing things like seeing whether there is a task due to be executed, or if there is I/O that needs to be processed, or whatever.

Baron Von Awsm

unread,
Nov 19, 2012, 10:14:57 PM11/19/12
to javas...@googlegroups.com
Jez
 
Thanks very much for your reply. Based on your comments I have refactored my code and I believe I have met my requirements.
 
The new code is at the bottom of this post. It appears to give me figures akin the figures produces by the windows resource monitor, but averaged over 10 seconds instead of 1 second as the windows monitor does.
 
I could not find a way to use CpuTimes.getCupUsage(...) to give me the resullt I wanted because, over a ten second period, it always returned 1. However the code I have now does the job. displayMemoryUsage() and displayCpuUsage() appears to give me the same figures I'm seeing in my windows resource monitor.
 
Thanks very much for your help and thanks very much for your efforts in getting this component out there.
 
>>>
Of course you wouldn't just sleep in real life, you'd set up a thread to poll every 10 seconds or so
<<<
 
Of course. This is just proof of concept code.
 
 
Cheers,
Baron
 

 private static void testJavaSysMon() {
  displayMemoryUsage();
  displayCpuStats();
  displayCpuUsage();
  return;
 }
 private static void displayMemoryUsage() {
  JavaSysMon systemMonitor = null;
  MemoryStats memoryUsage = null;
  int figure = 0;
  systemMonitor = new JavaSysMon();
  memoryUsage = systemMonitor.physical();
  figure = (int)Math.ceil(
   100 * ((double)(memoryUsage.getTotalBytes() - memoryUsage.getFreeBytes()) / memoryUsage.getTotalBytes()));
  logger.debug("Memory Usage: " + figure);
  return;
 }
 private static void displayCpuStats() {
  JavaSysMon systemMonitor = null;
  CpuTimes cpuTimes1 = null;
  CpuTimes cpuTimes2 = null;
  int figure = 0;
  systemMonitor = new JavaSysMon();
  cpuTimes1 = systemMonitor.cpuTimes();
  Methods.sleep(10000);
  cpuTimes2 = systemMonitor.cpuTimes();
  
  figure = (int)Math.round(100 * (
   (double) (cpuTimes2.getIdleMillis() - cpuTimes1.getIdleMillis())
    / (cpuTimes2.getTotalMillis() - cpuTimes1.getTotalMillis())
  ));
  logger.debug("Idle percentage: " + figure);
  figure = (int)Math.round(100 * (
   (double) (cpuTimes2.getUserMillis() - cpuTimes1.getUserMillis())
    / (cpuTimes2.getTotalMillis() - cpuTimes1.getTotalMillis())
  ));
  logger.debug("User percentage: " + figure);
  figure = (int)Math.round(100 * (
   (double) (cpuTimes2.getSystemMillis() - cpuTimes1.getSystemMillis())
    / (cpuTimes2.getTotalMillis() - cpuTimes1.getTotalMillis())
  ));
  logger.debug("System percentage: " + figure);
  return;
 }
 private static void displayCpuUsage() {
  JavaSysMon systemMonitor = null;
  CpuTimes cpuTimes1 = null;
  CpuTimes cpuTimes2 = null;
  int figure = 0;
  systemMonitor = new JavaSysMon();
  cpuTimes1 = systemMonitor.cpuTimes();
  Methods.sleep(10000);
  cpuTimes2 = systemMonitor.cpuTimes();
  figure = (int)Math.floor(100 * (
   (double)(cpuTimes2.getIdleMillis() - cpuTimes1.getIdleMillis())
    / (cpuTimes2.getTotalMillis() - cpuTimes1.getTotalMillis())
  ));
  logger.debug("CPU usage: " + (100 - figure));
  return;
 }
Reply all
Reply to author
Forward
0 new messages