Timing a task using wall clock time is not true in this post.
"Wall clock time" is the real-world elapsed time experienced by a user waiting for a task to complete. Prior to Java 1.5, measuring wall clock time was the conventional (and only) way to benchmark a Java task.
To measure wall clock time, call
java.lang.System . currentTimeMillis()
before and after the task and take the difference. The method returns the time in milliseconds (one thousandth of a second).Wall clock time is strongly affected by other activity on the system, such as background processes, other applications, disk or network activity, and updates to the display. On some systems, such as Windows, if the application is not on top, it will run at a lower priority and take longer. All of this can skew your benchmark results unless you are very careful to use an unloaded system and average across a large number of tests.
Using wall clock time isn't necessarily bad if you're interested in what the user will experience. But it makes it hard to get consistent benchmark numbers that reveal your own application's problems.
If we use getProcessCpuTime()
, it seems that we measure all time of the JVM.
So how to differentiate JVM intrinsic threads(below) and java program threads (single or multithread) so that I can measure the real Java program threads CPU time?
enum ThreadType { // **intrinsic threads**
vm_thread,
cgc_thread, // Concurrent GC thread
pgc_thread, // Parallel GC thread
java_thread, // Java, CodeCacheSweeper, JVMTIAgent and Service threads.
compiler_thread,
watcher_thread,
os_thread
};
In this post, main_thread
seems to be a single thread. Is mutator thread created by JVM?
(src/share/vm/runtime/thread.cpp)
3191 // Attach the main thread to this os thread
3192 JavaThread* main_thread = new JavaThread();
3193 main_thread->set_thread_state(_thread_in_vm);
3194 // must do this before set_active_handles and initialize_thread_local_storage
3195 // Note: on solaris initialize_thread_local_storage() will (indirectly)
3196 // change the stack size recorded here to one based on the java thread
3197 // stacksize. This adjusted size is what is used to figure the placement
3198 // of the guard pages.
3199 main_thread->record_stack_base_and_size();
3200 main_thread->initialize_thread_local_storage();
What if the Java program is multithreaded, like the program below?
// Java code for thread creation by implementing
// the Runnable Interface
class MultithreadingDemo implements Runnable
{
public void run()
{
try
{
// Displaying the thread that is running
System.out.println ("Thread " +
Thread.currentThread().getId() +
" is running");
}
catch (Exception e)
{
// Throwing an exception
System.out.println ("Exception is caught");
}
}
}
int n = 8; // Number of threads
for (int i=0; i<8; i++)
{
Thread object = new Thread(new MultithreadingDemo());
object.start();
}
Why MXBeans only returns 1 main thread?
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.ArrayDeque;
import java.util.LinkedList;
public class MultiThread {
/** Get CPU time in nanoseconds. */
public long getCpuTime( ) {
ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
return bean.isCurrentThreadCpuTimeSupported( ) ?
bean.getCurrentThreadCpuTime( ) : 0L;
}
/** Get user time in nanoseconds. */
public long getUserTime( ) {
ThreadMXBean bean = ManagementFactory.getThreadMXBean( );
return bean.isCurrentThreadCpuTimeSupported( ) ?
bean.getCurrentThreadUserTime( ) : 0L;
}
public static void main(String[] args) {
// deque operation
//ArrayDeque<LinkedList<Integer>> deque = new ArrayDeque<LinkedList<Integer>>();
ArrayDeque<Byte[]> deque = new ArrayDeque<Byte[]>();
int objectSize = 1024;
int xxx = 0;
// expand old and young heap size
for(long i = 0; i < 1500; i++){
for(int j = 0; j < 300; j++){
deque.addLast(new Byte[objectSize]);
}
for(int m = 0; m < 65535; m++){
xxx += 1;
xxx -= 1;
}
for(int j = 0; j < 20; j++){
deque.removeLast();
}
}
for(long i = 0; i < 1500; i++){
for(int j = 0; j < 300; j++){
deque.addLast(new Byte[objectSize]);
}
for(int m = 0; m < 65535; m++){
xxx += 1;
xxx -= 1;
}
for(int j = 0; j < 300; j++){
deque.removeFirst();
}
}
int n = 8; // Number of threads
for (int i=0; i<8; i++)
{
Thread object = new Thread(new MultithreadingDemo());
object.start();
}
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
//don't need monitor and synchronizer info,only get thread and stack info。
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
for (ThreadInfo threadInfo : threadInfos) {
String tName = threadInfo.getThreadName();
long tId = threadInfo.getThreadId();
System.out.println(tName + "," + tId);
}
}
}