JDK-8328618 : HotspotInternalMBeans should be removed
  • Type: Enhancement
  • Component: core-svc
  • Sub-Component: javax.management
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2024-03-20
  • Updated: 2024-09-11
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.
Other
tbdUnresolved
Related Reports
Relates :  
Description
In java.management, the sun.management.HotspotInternalMBean is an undocumented, unsupported and experimental interface.

HotspotInternalMBean can be manually instantiated by a Java app, then the MBeans retrieved by name.  Or, ManagementFactoryHelper has methods to return them, e.g. getHotspotRuntimeMBean().

The separate class java.lang.management.ManagementFactory is the documented factory class for getting managed beans for the Java platform. 

Creating a HotspotInternalMBean causes creation of other sun.management MBeans, which are then registered with the MBean server:

HotspotClassLoading implements HotspotClassLoadingMBean 
HotspotMemory implements HotspotMemoryMBean 
HotspotRuntime implements HotspotRuntimeMBean 
HotspotThread implements HotspotThreadMBean 
HotspotCompilation implements HotspotCompilationMBean

These largely provide an interface to VMManagement jvm, and mostly return performance counters, as could be accessed with jcmd PerfCounter.print.


We should check if anything of use here is not adequately available by other MBeans, or jstat, or any other mechanism.  These unpublicised MBeans should be removed if they provide no real value.


Comments
HotspotInternalMBean and friends and any native code which is specific to them should be uncontroversial to remove. For any other layers, if e.g. the management library has native methods that are not called within the JDK, we can think about them separately.
22-03-2024

Thanks for your excellent analysis of where these beans get their data, Kevin! I've been trying to identify what native code falls out of use when we remove the Hotspot-internal MBeans from the Java side. I found that following methods in sun.management.VMManagement fall out of use: * getSafepointCount() * getTotalSafepointTime() * getSafepointSyncTime() * getTotalApplicationNonStoppedTime() * getLoadedClassSize() * getUnloadedClassSize() * getClassLoadingTime() * getMethodDataSize() * getInitializedClassCount() * getClassInitializationTime() * getClassVerificationTime() With the above methods removed, the following constants in src/hotspot/share/include/jmm.h fall out of use: * JMM_SAFEPOINT_COUNT * JMM_TOTAL_STOPPED_TIME_MS * JMM_TOTAL_SAFEPOINTSYNC_TIME_MS * JMM_TOTAL_APP_TIME_MS * JMM_CLASS_LOADED_BYTES * JMM_CLASS_UNLOADED_BYTES * JMM_TOTAL_CLASSLOAD_TIME_MS * JMM_METHOD_DATA_SIZE_BYTES * JMM_CLASS_INIT_TOTAL_COUNT * JMM_CLASS_INIT_TOTAL_TIME_MS * JMM_CLASS_VERIFY_TOTAL_TIME_MS With the above libmanagement methods / constants removed, the following native service methods fall out of use: * RuntimeService::safepoint_count(); * RuntimeService::safepoint_time_ms(); * RuntimeService::safepoint_sync_time_ms(); * RuntimeService::application_time_ms(); * ClassLoadingService::loaded_class_bytes(); * ClassLoadingService::unloaded_class_bytes(); * ClassLoader::classloader_time_ms(); * ClassLoadingService::class_method_data_size(); * ClassLoader::class_init_count(); * ClassLoader::class_init_time_ms(); * ClassLoader::class_verify_time_ms(); I'm wondering if we should follow the unuse all the way down and aim to remove all of the above as part of this cleanup? Or does it make sense to keep some or all of these around?
22-03-2024

Notes on what is in the HotspotXXXMBeans: HotspotClassLoading implements HotspotClassLoadingMBean Compared to ClasLoadingMXBean, this has additional methods for overall class loading time, loaded classes size, and unloaded classes size. e.g. getLoadedClassSize() calls into native VMManagement.c: getLoadedClassSize() calls jmm_interface->GetLongAttribute(env, NULL, JMM_CLASS_LOADED_BYTES); calls ClassLoadingService::loaded_class_bytes() which returns _classbytes_loaded->get_value() + _shared_classbytes_loaded->get_value() which are "sun.cls.loadedBytes" + "sun.cls.sharedLoadedBytes" HotspotMemory implements HotspotMemoryMBean Only one method to return all java.gc, com.sun.gc, and sun.gc perf counters. HotspotRuntime implements HotspotRuntimeMBean Compared to RuntimeMXBean, this has additional methods for safepoint info, but they simply relate to perf counters. getSafepointCount() calls into VMManagementImpl.java native VMManagementImpl.c: return jmm_interface->GetLongAttribute(env, NULL, JMM_SAFEPOINT_COUNT); management.cpp: calls RuntimeService::safepoint_count(); which queries perf counter sun.rt.safepoints also methods to access: jvm.getTotalSafepointTime() == jmm_interface->GetLongAttribute(env, NULL, JMM_TOTAL_STOPPED_TIME_MS); == RuntimeService::safepoint_time_ms(); == perf counter "sun.rt.safepointTime" (in TICKS, convert with Management::ticks_to_ms()) jvm.getSafepointSyncTime(); == management's JMM_TOTAL_SAFEPOINTSYNC_TIME_MS == RuntimeService::safepoint_sync_time_ms() == "sun.rt.safepointSyncTime" TICKS converted to ms. HotspotThread implements HotspotThreadMBean Compared to ThreadMXBean: ThreadMXBean.getThreadCount does not count vm threads. HotspotThread: Gets "internal" thread info, unlike ThreadMXBean. But definition is unclear. Only two methods, plus one to list all relevant perf counters. public native int getInternalThreadCount() returns = jmm_interface->GetLongAttribute(env, NULL,JMM_VM_THREAD_COUNT); where management.cpp: get_vm_thread_count() uses VmThreadCountClosure which counts, ignoring JavaThreads and those hidden from view (but hidden from view means GC, Compiler etc..., so what does "internal" mean?) public native int getInternalThreadTimes0(String[] names, long[] times); HotspotThread.c : return jmm_interface->GetInternalThreadTimes(env, names, times); management.cpp: jmm_GetInternalThreadTimes(...) uses ThreadTimesClosure which // exclude externally visible JavaThreads Meaning: don't show GC, Compiler, string dedup, monitor deflation, service threads. Sums os::thread_cpu_time(thread) for all visible threads. compare with: com.sun.management.ThreadMXBean extends java.lang.management.ThreadMXBean ThreadImpl: getThreadCpuTime: calls native getThreadTotalCpuTime0 ThreadImpl.c: return jmm_interface->GetThreadCpuTimeWithKind management.cpp: jmm_GetThreadCpuTimeWithKind uses os::thread_cpu_time() (i.e. uses the same measure of time, difference in which threads are measured) HotspotCompilation implements HotspotCompilationMBean Comparision with CompilationMXBean: CompilationMXBean does not do very much: getTotalCompilationTime() and two other less interesting methods: getName(), isCompilationTimeMonitoringSupported(). HotspotCompilation is ALL about reading perf counters. The information available by HotspotCompilation is all in: jcmd PID PerfCounter.print | egrep "java.ci|sun.ci|com.sun.ci" (I don't see any com.sun.ci counters)
20-03-2024