2

I was reading section ThreadPools section 6.2.3 java concurrency in practice by Brian Goetz. A statement I came across is "Reusing an existing thread instead of creating a new one amortizes thread creation and teardown costs."

1) I wanted to get some metrics involved in the java thread creation process which as we know will involve the creation/allocation of a stack and the program counter register to the created thread. Is there a tool/utility/visual vm tracer/jmx bean that I can use for the same which can give me some indicators on memory and time usage for thread creation. Can some one guide me to the same ?

2) Is there a text which can guide me to the whole process of java thread creation in detail which should cover the respective OS calls to windows ?

Why is creating a Thread said to be expensive? has given me some information, but I wanted to study the internals of java thread creation in detail

Thanks

Community
  • 1
  • 1
userx
  • 3,713
  • 5
  • 32
  • 38
  • 1
    Have you looked at jconsole which comes with the distribution of the jdk? – Shervin Asgari Dec 18 '13 at 08:38
  • 2
    @Shervin - I have looked into jconsole and jvisualvm, since they both support mbeans, I went to ThreadImpl.getThreadAllocatedBytes, is it that the indicator of java stack size ?Also I couldn't find any indicator for time taken for Thread creation ? Also could you help me on point number 2, I am looking for some great theory on java thread construction process and the concerned OS level calls for Windows. – userx Dec 18 '13 at 09:40

1 Answers1

0

Concerning your second question:

2) Is there a text which can guide me to the whole process of java thread creation in detail which should cover the respective OS calls to windows ?

This guide, though slightly off topic is great: http://blog.jamesdbloom.com/JVMInternals.html

And the following book The Java Virtual Machine Specification, Java SE 7 Edition (google book link) explains the JVM internals in depth and as such would be my best bet (disclaimer: I had only skimmed through the visible parts)

If that is not good enough, you could always download the source code for the open jdk (7) and crawl through the code...

An excerpt from the open jdk code is this (openjdk\hotspot\src\share\vm\runtime\thread.cpp - c'tor):

// Base class for all threads: VMThread, WatcherThread, ConcurrentMarkSweepThread,
// JavaThread


Thread::Thread() {
  // stack and get_thread
  set_stack_base(NULL);
  set_stack_size(0);
  set_self_raw_id(0);
  set_lgrp_id(-1);

  // allocated data structures
  set_osthread(NULL);
  set_resource_area(new ResourceArea());
  set_handle_area(new HandleArea(NULL));
  set_active_handles(NULL);
  set_free_handle_block(NULL);
  set_last_handle_mark(NULL);

  // This initial value ==> never claimed.
  _oops_do_parity = 0;

  // the handle mark links itself to last_handle_mark
  new HandleMark(this);

  // plain initialization
  debug_only(_owned_locks = NULL;)
  debug_only(_allow_allocation_count = 0;)
  NOT_PRODUCT(_allow_safepoint_count = 0;)
  NOT_PRODUCT(_skip_gcalot = false;)
  CHECK_UNHANDLED_OOPS_ONLY(_gc_locked_out_count = 0;)
  _jvmti_env_iteration_count = 0;
  set_allocated_bytes(0);
  _vm_operation_started_count = 0;
  _vm_operation_completed_count = 0;
  _current_pending_monitor = NULL;
  _current_pending_monitor_is_from_java = true;
  _current_waiting_monitor = NULL;
  _num_nested_signal = 0;
  omFreeList = NULL ;
  omFreeCount = 0 ;
  omFreeProvision = 32 ;
  omInUseList = NULL ;
  omInUseCount = 0 ;

  _SR_lock = new Monitor(Mutex::suspend_resume, "SR_lock", true);
  _suspend_flags = 0;

  // thread-specific hashCode stream generator state - Marsaglia shift-xor form
  _hashStateX = os::random() ;
  _hashStateY = 842502087 ;
  _hashStateZ = 0x8767 ;    // (int)(3579807591LL & 0xffff) ;
  _hashStateW = 273326509 ;

  _OnTrap   = 0 ;
  _schedctl = NULL ;
  _Stalled  = 0 ;
  _TypeTag  = 0x2BAD ;

  // Many of the following fields are effectively final - immutable
  // Note that nascent threads can't use the Native Monitor-Mutex
  // construct until the _MutexEvent is initialized ...
  // CONSIDER: instead of using a fixed set of purpose-dedicated ParkEvents
  // we might instead use a stack of ParkEvents that we could provision on-demand.
  // The stack would act as a cache to avoid calls to ParkEvent::Allocate()
  // and ::Release()
  _ParkEvent   = ParkEvent::Allocate (this) ;
  _SleepEvent  = ParkEvent::Allocate (this) ;
  _MutexEvent  = ParkEvent::Allocate (this) ;
  _MuxEvent    = ParkEvent::Allocate (this) ;

#ifdef CHECK_UNHANDLED_OOPS
  if (CheckUnhandledOops) {
    _unhandled_oops = new UnhandledOops(this);
  }
#endif // CHECK_UNHANDLED_OOPS
#ifdef ASSERT
  if (UseBiasedLocking) {
    assert((((uintptr_t) this) & (markOopDesc::biased_lock_alignment - 1)) == 0, "forced alignment of thread object failed");
    assert(this == _real_malloc_address ||
           this == (void*) align_size_up((intptr_t) _real_malloc_address, markOopDesc::biased_lock_alignment),
           "bug in forced alignment of thread objects");
  }
#endif /* ASSERT */
}
Yaneeve
  • 4,751
  • 10
  • 49
  • 87
  • 1
    I have followed Inside the java virtual machine by Bill Venners, it gives me an understanding of the internal data structures . Your post above definitely shows a way and which is to debug the native methods, stuff like start0() in Thread. I think it will help me understand from the code's perspective. Thanks. Though finding a right debugger. – userx Dec 18 '13 at 13:33