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