Today in France, we celebrate ""
Posts
04/07/10 : Android sorting
16/06/10 : Flex XML parsing
15/06/10 : Android settings
14/06/10 : Pax daemon
10/06/10 : Bundle CPU %
04/06/10 : Wicket CheckBox
03/06/10 : Thread monitor

By tag
Ajax
Android
AspectJ
Flex
Java
JMX
OSGi
Shell
Wickets

Here are some lights and tips on various Object Oriented Programming aspects that I would have dealt with during my software development and architecture activities..., for sharing.

"Beauty is an inexhaustible source of happyness for the one who discovers it" (Alexis Carrel)



Thursday, 10 June 2010

OSGi bundle CPU usage

Question : how to compute the CPU used by an OSGi bundle ?

Answer :
- manage a Map table for the threads list owned by any given OSGi bundle
- rely on the JMX standard API


Details :

Step #1 : consider these attributes, based on JMX Beans :

private Map<Bundle, ArrayList<Thread>> threadMap =
new HashMap<Bundle, ArrayList<Thread>>();
private Map<Long, Long> threadTime =
new HashMap<Long, Long>();
private RuntimeMXBean runTimeBean =
ManagementFactory.getRuntimeMXBean();
private ThreadMXBean threadBean =
ManagementFactory.getThreadMXBean();
private int nbProcs =
ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors();
private long timerStart;
private long timerDelay;

Where 'timerStart' and 'timerDelay' should be updated as follows :

timerStart = runTimeBean.getUptime(); // init time
timerDelay = (runTimeBean.getUptime() - timerStart) * 1000000L; // window time

Step #2 : assuming that the 2 Map instances are being successfully maintained while any bundle is getting started/stopped on the OSGi framework, the percentage of CPU used by a given bundle can be computed as follows :

/**
* Get the percentage of CPU used by a bundle
*
* @param bundle
* The monitored bundle instance
* @return The percentage of CPU used
*/
private float getBundlePercentTime(Bundle bundle)
{
long cpuTime = 0L; // CPU used in nanoseconds
float cpuPercent = 0F; // percentage of CPU used

if ((cpuTime = getBundleCpuTime(bundle)) > 0)
{
cpuPercent = Math.min(0.99F, (float) cpuTime / (float) timerDelay);
}

return cpuPercent * 100.0F;
}


/**
* Get the overall CPU used by a bundle
*
* @param bundle
* The monitored bundle instance
* @return Its actual CPU usage in nanoseconds
*/
private long getBundleCpuTime(Bundle bundle)
{
long cpuTime = 0L; // CPU used in nanoseconds

if (threadMap.containsKey(bundle))
{
for (Thread thread : threadMap.get(bundle))
{
cpuTime += updateThreadCpuTime(thread.getId());
}
}
else
{
// Error handling
}

return cpuTime;
}


/**
* Refresh the CPU used by a thread, given its identifier
*
* @param threadID
* The monitored thread identifier
* @return Its actual CPU usage in nanoseconds
*/
private long updateThreadCpuTime(long threadID)
{
long diffCpu = 0L; // actual CPU difference in nanoseconds
long currentCpu = 0L; // actual CPU in nanoseconds
long previousCpu = 0L; // previous CPU in nanoseconds
Long previousCpuL = 0L; // previous CPU in nanoseconds

// Compute actual CPU usage
if ((previousCpuL = threadTime.get(threadID)) != null)
previousCpu = previousCpuL.longValue();
if ((currentCpu = threadBean.getThreadCpuTime(threadID)) >= 0)
diffCpu = currentCpu - previousCpu;

// Map table update
threadTime.put(threadID, currentCpu);

return diffCpu;
}

No comments:

Post a Comment

Previous Post Next Post