JDK-8010862 : The Method counter fields used for profiling can be allocated lazily
  • Type: Enhancement
  • Component: embedded
  • Sub-Component: hotspot
  • Affected Version: 8
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2013-03-27
  • Updated: 2018-01-10
  • Resolved: 2013-04-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 Other
8Fixed hs25Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
The following 7 Method fields are used for interpreter/tiered compilation profiling. These fields are not used until a java method is executed. 

  int               _interpreter_invocation_count; 
  u2                _interpreter_throwout_count; 
  u2                _number_of_breakpoints;     
  InvocationCounter _invocation_counter;        
  InvocationCounter _backedge_counter;        
#ifdef TIERED
  float             _rate;                    
  jlong             _prev_time;              
#endif

Move those fields into a separate MethodCounters object referenced from Method. The counter object for a specific method can be allocated upon the first time when any of the fields is modified.

A separate data structer is used for the interpreter counters instead of adding the counters to MethodData, because the MethodData might not have the same life span as the interpreter counters. For example when TieredCompilation is not enabled, the MethodData is not allocated until the interpreter counter reaches InterpreterProfileLimit. Allocating the MethodData early would waste memory for non-hot methods which only execute a few times. Also the MethodData is only allocated when ProfileInterpreter is enabled, which is the default case for c2 but not for c1. Under TieredCompilation, there are cases where MethodData exist but the interpreter counters are never accessed.

Comments
Good question. For these profiling fields, there seems no measurable performance impact. Following are performance data measured on ARM (both c1 and c2) and x86 (c2 only), no noticeable degradation: ============================================================================== logs.spec.base.x86: Benchmark Samples Mean Stdev Geomean Weight specjvm98 8 557.80 4.32 ============================================================================== logs.spec.x86: Benchmark Samples Mean Stdev %Diff P Significant specjvm98 8 559.14 4.92 0.24 0.574 * ============================================================================== ============================================================================== logs.jbb.base.x86: Benchmark Samples Mean Stdev Geomean Weight specjbb2005 3 56496.28 736.48 ============================================================================== logs.jbb.x86: Benchmark Samples Mean Stdev %Diff P Significant specjbb2005 3 56434.70 1125.70 -0.11 0.941 * ============================================================================== ============================================================================== logs.spec.base.c1.arm: Benchmark Samples Mean Stdev Geomean Weight specjvm98 8 65.94 0.22 ============================================================================== logs.spec.c1.arm: Benchmark Samples Mean Stdev %Diff P Significant specjvm98 8 65.86 0.26 -0.12 0.510 * ============================================================================== ============================================================================== logs.spec.c2.base.arm: Benchmark Samples Mean Stdev Geomean Weight specjvm98 8 75.40 1.20 ============================================================================== logs.spec.c2.arm: Benchmark Samples Mean Stdev %Diff P Significant specjvm98 8 76.21 1.58 1.08 0.267 * ==============================================================================
27-03-2013

Thanks for clarifying. So generalizing this we should be able to separate the 'static metadata" that is needed when a class is loaded and parsed (and so all method objects etc are created); versus the dynamic meta-data that is only needed when we actually execute a given method. The question then is: what is the performance impact for the extra indirection when we do need it?
27-03-2013

I remeasured runtime memory usage (VmRSS) on ubuntu x86 (32-bit) with the profiling fields lazy allocation: Before After Saving Launching Eclipse 257724kB 249576kB 8M ClassLoadingTest 88744kB 85192kB 3.5M HelloWorld 12356kB 12284kB 72K *Eclipse memory usage seems to fluctuate in a bounded rangeduring initial launching, I took the memory usage snapshot after eclipse started for 5min and in a "stable" statein above measurement.
27-03-2013

large percent of the loaded java method probably are never executed. In one of my experiment with eclipse, roughly about 30% of the loaded java methods were executed when eclipse is launched. None of the profiling fields are used until a java method is executed, however they are always allocated along with the other Method field for every loaded java methods.
27-03-2013

But won't we always end up using these fields for every Java method?
27-03-2013