(See: java.lang.management.MemoryPoolMXBean に関するドキュメント) (<= 特に java.lang.management.MemoryPoolMXBean.setUsageThreshold() メソッドと java.lang.management.MemoryPoolMXBean.setCollectionUsageThreshold() メソッドに関する部分)
内部的には, 閾値超過の発生の有無や発生回数を記録するために sun.management.Sensor というオブジェクトが使われている. 処理は以下のようになる.
(この際, ついでに MemoryMXBean に登録されているリスナーへの通知処理も行われる)
なお, 正確に言うと sun.management.Sensor 自体は abstract クラスであり, 実際に使われるのはサブクラスである sun.management.PoolSensor と sun.management.CollectionSensor になる. それぞれの役割分担は以下の通り.
((cite: jdk/src/share/classes/sun/management/MemoryPoolImpl.java))
/**
* PoolSensor will be triggered by the VM when the memory
* usage of a memory pool is crossing the usage threshold.
* The VM will not trigger this sensor in subsequent crossing
* unless the memory usage has returned below the threshold.
*/
class PoolSensor extends Sensor {
((cite: jdk/src/share/classes/sun/management/MemoryPoolImpl.java))
/**
* CollectionSensor will be triggered and cleared by the VM
* when the memory usage of a memory pool after GC is crossing
* the collection threshold.
* The VM will trigger this sensor in subsequent crossing
* regardless if the memory usage has changed siince the previous GC.
*/
class CollectionSensor extends Sensor {
一部の MemoryPool オブジェクトは閾値設定機能に対応していない. 対応の有無は MemoryPool オブジェクトのクラスによって決まっており, 具体的には以下の通り.
(なお, 対応有無の情報は各 MemoryPool オブジェクトの生成時に設定され, 各 MemoryPool オブジェクト内の ThresholdSupport オブジェクトに格納されている (See: MemoryPool::MemoryPool()))
collection usage threshold 機能 | usage threshold 機能 | |
---|---|---|
CodeHeapPool | 非対応(※1) | 対応(※2) |
CollectedMemoryPool のサブクラス | どのサブクラスでも対応(※3) | Old や Perm は対応. Eden や Survivor は非対応 (※4) |
sun.management.MemoryPoolImpl.setUsageThreshold() -> sun.management.MemoryPoolImpl.setPoolUsageSensor() -> Java_sun_management_MemoryPoolImpl_setPoolUsageSensor() -> jmm_SetPoolSensor() -> MemoryPool::set_usage_sensor_obj() -> MemoryPool::set_sensor_obj_at() -> sun.management.MemoryPoolImpl.setUsageThreshold0() -> Java_sun_management_MemoryPoolImpl_setUsageThreshold0() -> jmm_SetPoolThreshold() -> LowMemoryDetector::recompute_enabled_for_collected_pools() -> LowMemoryDetector::detect_low_memory(MemoryPool* pool) -> SensorInfo::set_gauge_sensor_level() -> SensorInfo::has_pending_requests() -> Monitor::notify_all() (<= もし送信すべき通知があれば ServiceThread を起床させる)
sun.management.MemoryPoolImpl.setCollectionUsageThreshold() -> sun.management.MemoryPoolImpl.setPoolCollectionSensor() -> Java_sun_management_MemoryPoolImpl_setPoolCollectionSensor() -> jmm_SetPoolSensor() -> MemoryPool::set_gc_usage_sensor_obj() -> MemoryPool::set_sensor_obj_at() -> sun.management.MemoryPoolImpl.setCollectionUsageThreshold0() -> Java_sun_management_MemoryPoolImpl_setCollectionThreshold0() -> jmm_SetPoolThreshold() -> (同上)
(sun.management.MemoryImpl は sun.management.NotificationEmitterSupport のサブクラスなので, MemoryImpl オブジェクトに対して addNotificationListener() メソッドを呼び出すと sun.management.NotificationEmitterSupport.addNotificationListener() が呼び出される)
sun.management.NotificationEmitterSupport.addNotificationListener()
(GC 終了後に TraceMemoryManagerStats のデストラクタから呼び出される)
(ここでの処理は, Java ヒープを担当する MemoryPool の gc usage threshold のチェック)
TraceMemoryManagerStats::~TraceMemoryManagerStats() -> MemoryService::gc_end() -> GCMemoryManager::gc_end() -> LowMemoryDetector::detect_after_gc_memory() -> SensorInfo::set_counter_sensor_level() -> LowMemoryDetector::detect_low_memory(MemoryPool* pool) -> (同上)
(メモリ確保の slow-path から呼び出される)
(ここでの処理は, Java ヒープを担当する MemoryPool の usage threshold のチェック)
post_allocation_notify() -> LowMemoryDetector::detect_low_memory_for_collected_pools() -> LowMemoryDetector::is_enabled_for_collected_pools() -> LowMemoryDetector::detect_low_memory(MemoryPool* pool) -> (同上)
(GC 終了後に呼び出される)
(ここでの処理は, Java ヒープを担当する MemoryPool の usage threshold のチェック)
MemoryService::track_memory_usage() -> LowMemoryDetector::detect_low_memory() -> SensorInfo::set_gauge_sensor_level() -> SensorInfo::has_pending_requests() -> Monitor::notify_all() (<= もし送信すべき通知があれば ServiceThread を起床させる)
(CodeCache でのメモリの確保/解放時に呼び出される)
(ここでの処理は, CodeCache 用 MemoryPool の usage threshold のチェック)
MemoryService::track_code_cache_memory_usage() -> MemoryService::track_memory_pool_usage() -> LowMemoryDetector::detect_low_memory(MemoryPool* pool) -> (同上)
ServiceThread::service_thread_entry() -> LowMemoryDetector::has_pending_requests() -> LowMemoryDetector::process_sensor_changes() -> SensorInfo::process_pending_requests() -> SensorInfo::trigger() -> sun.management.Sensor.trigger() -> sun.management.PoolSensor.triggerAction() or sun.management.CollectionSensor.triggerAction() -> sun.management.MemoryImpl.createNotification() -> SensorInfo::clear() -> sun.management.Sensor.clear() -> sun.management.PoolSensor.clearAction() or sun.management.CollectionSensor.clearAction()
sun.management.MemoryPoolImpl.isUsageThresholdExceeded() -> sun.management.Sensor.isOn()
sun.management.MemoryPoolImpl.getUsageThresholdCount() -> sun.management.Sensor.getCount()
sun.management.MemoryPoolImpl.isCollectionUsageThresholdExceeded() -> sun.management.Sensor.isOn()
sun.management.MemoryPoolImpl.getCollectionUsageThresholdCount() -> sun.management.Sensor.getCount()
(#Under Construction) See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
(#Under Construction) See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
See: here for details
(#Under Construction) See: here for details
See: here for details
(#Under Construction) See: here for details
See: here for details
(#Under Construction) See: here for details
(#Under Construction) See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.