|
JavaTM 2 Platform Standard Ed. 6 |
|||||||||
上一個類別 下一個類別 | 框架 無框架 | |||||||||
摘要: 巢狀 | 欄位 | 建構子 | 方法 | 詳細資訊: 欄位 | 建構子 | 方法 |
public interface MemoryPoolMXBean
記憶體池的管理介面。記憶體池表示由 Java 虛擬機器管理的記憶體資源,由一個或多個記憶體管理器
對記憶體池進行管理。
Java 虛擬機器具有此介面的實作類別的一個或多個實例。實作此介面的實例是 MXBean,可以通過調用 ManagementFactory.getMemoryPoolMXBeans()
方法或從平臺 MBeanServer
方法獲得。
在 MBeanServer 中惟一標識記憶體池的 MXBean 的 ObjectName 為:
java.lang:type=MemoryPool
,name=pool's name
Java 虛擬機器具有一個用於物件分派的堆積(heap)空間,還包含用於方法區域和 Java 虛擬機器執行的非堆積(heap)空間記憶體。Java 虛擬機器可以有一個或多個記憶體池。每個記憶體池表示一個記憶體區域,此記憶體區域可為以下型別之一:
getUsage()
方法提供了記憶體池當前使用量的估計數。對於垃圾回收記憶體池,已使用的記憶體包括由池中所有物件(包括可到達 物件和不可達到 物件)佔用的記憶體。
通常,此方法是一個輕量操作,用於獲取近似記憶體使用量。對於某些記憶體池(例如,當物件未連續打包時),此方法可能成為開銷巨大的操作,要求進行計算以確定當前的記憶體使用量。如果是這樣,實作應該加以註釋。
getPeakUsage()
方法返回,通過調用 resetPeakUsage()
方法可將其重置。
setUsageThreshold
方法設置使用量閾值。如果閾值設置為正數,將啟用此記憶體池中的使用量閾值超過檢查。如果使用率閾值設置為零,將禁用此記憶體池的使用量閾值超過檢查。isUsageThresholdSupported()
方法可用於確定是否支持此功能。
Java 虛擬機器在其最恰當的時候(通常在垃圾回收時)會對記憶體池逐個進行使用量閾值超過檢查。每個記憶體池均維護一個使用量閾值計數
,每次 Java 虛擬機器檢測到記憶體池使用量超過閾值,此值都會加 1。
此可管理的使用量閾值屬性設計用於以低開銷監視記憶體使用量增加的趨勢。使用量閾值可能不適合某些記憶體池。例如,生存期垃圾回收器是在很多 Java 虛擬機器實作中都使用的一種常見的垃圾回收演算法,它按照生存時間管理劃分為兩代或多代的物件。很多對象都分派在最新的一代(稱為新生記憶體池)。新生記憶體池的設計使其很容易被填滿,回收新生記憶體池將會釋放其大部分記憶體空間,因為這種記憶體池包含了大多數生存時間短的物件,以及大多數在垃圾回收時不可到達的物件。在這種情況下,新生記憶體池不支持使用量閾值會更為合適。此外,如果在一個記憶體池中進行物件分派的開銷很小(例如,只是原子指針交換),Java 虛擬機器將可能不支持該記憶體池的使用量閾值,因為使用量閾值的開銷比物件分派的開銷大。
通過調用所有記憶體池的 getUsage()
方法或調用支持使用量閾值的記憶體池的 isUsageThresholdExceeded()
方法,應用程序可以持續監視其記憶體使用量。以下的範例程式碼具有一個專門用於任務分派和處理的執行緒。每隔一段時間,它將根據其記憶體使用量確定是否應當接受和處理新任務。如果記憶體使用量超過了其使用量閾值,它會將所有未處理的任務重新分派給其他 VM 並停止接受新任務,直到記憶體使用量低於其使用量閾值。
// Assume the usage threshold is supported for this pool. // Set the threshold to myThreshold above which no new tasks // should be taken. pool.setUsageThreshold(myThreshold); .... boolean lowMemory = false; while (true) { if (pool.isUsageThresholdExceeded()) { // potential low memory, so redistribute tasks to other VMs lowMemory = true; redistributeTasks(); // stop receiving new tasks stopReceivingTasks(); } else { if (lowMemory) { // resume receiving tasks lowMemory = false; resumeReceivingTasks(); } // processing outstanding task ... } // sleep for sometime try { Thread.sleep(sometime); } catch (InterruptedException e) { ... } }
getUsageThresholdCount()
方法返回的使用量閾值計數可用於確定在兩次輪詢之間返回的記憶體使用量是否低於閾值。
以下是另一個範例,該範例在記憶體池出現記憶體空間不足時將採取一些操作,並會忽略在操作處理期間的記憶體使用量變化。
// Assume the usage threshold is supported for this pool. // Set the threshold to myThreshold which determines if // the application will take some action under low memory condition. pool.setUsageThreshold(myThreshold); int prevCrossingCount = 0; while (true) { // A busy loop to detect when the memory usage // has exceeded the threshold. while (!pool.isUsageThresholdExceeded() || pool.getUsageThresholdCount() == prevCrossingCount) { try { Thread.sleep(sometime) } catch (InterruptException e) { .... } } // Do some processing such as check for memory usage // and issue a warning .... // Gets the current threshold count. The busy loop will then // ignore any crossing of threshold happens during the processing. prevCrossingCount = pool.getUsageThresholdCount(); }
使用量閾值通知將由 MemoryMXBean
發出。當 Java 虛擬機器檢測到記憶體池的記憶體使用量達到或超過其記憶體使用量閾值時,虛擬機器將觸發 MemoryMXBean ,發出使用量閾值超過通知
。直到使用量降低到閾值以下,然後再次超過了閾值,才會再次產生使用量閾值超過通知。
以下範例程式碼實作了與以上範例相同的邏輯,但使用了使用量閾值通知機制(而非輪詢)來檢測低記憶體情況。在此範例程式碼中,接收到通知時,通知偵聽器將通知另一個執行緒執行實際的操作,如重新分派未處理的任務、停止接受任務,或恢復接受任務等。handleNotification 方法應該設計為完成很少的工作,且無延遲地返回,以避免導致交付後續通知時出現延遲。耗時的操作應該使用獨立的執行緒來執行。通知偵聽器可以由多個執行緒共時調用,因此偵聽器執行的任務應該進行適當地同步。
class MyListener implements javax.management.NotificationListener { public void handleNotification(Notification notification, Object handback) { String notifType = notification.getType(); if (notifType.equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)) { // potential low memory, notify another thread // to redistribute outstanding tasks to other VMs // and stop receiving new tasks. lowMemory = true; notifyAnotherThread(lowMemory); } } } // Register MyListener with MemoryMXBean MemoryMXBean mbean = ManagementFactory.getMemoryMXBean(); NotificationEmitter emitter = (NotificationEmitter) mbean; MyListener listener = new MyListener(); emitter.addNotificationListener(listener, null, null); // Assume this pool supports a usage threshold. // Set the threshold to myThreshold above which no new tasks // should be taken. pool.setUsageThreshold(myThreshold); // Usage threshold detection is enabled and notification will be // handled by MyListener. Continue for other processing. ....
無法保證 MemoryMXBean 何時發出閾值通知和交付通知。當調用通知偵聽器時,記憶體池的記憶體使用量可能已經多次超過使用量閾值。MemoryNotificationInfo.getCount()
方法將返回建構通知時記憶體使用量已超過使用量閾值的次數。可以將此值與 getUsageThresholdCount()
返回的當前使用量閾值計數進行比較,以確定是否出現了此類別情況。
MemoryMXBean
發出回收使用量超過通知
。此外,回收使用量閾值計數
將增加 1。
isCollectionUsageThresholdSupported()
方法可用於確定是否支持此功能。
Java 虛擬機器按記憶體池執行回收使用量閾值檢查。如果回收使用量閾值設置為正數,則將啟用此檢查。如果回收使用量閾值設置為零,將在此記憶體池上禁用此檢查。預設值為零。Java 虛擬機器將在垃圾回收時執行回收使用量閾值檢查。
某些垃圾回收記憶體池可能選擇不支持回收使用量閾值。例如,僅由持續共時垃圾回收器管理的記憶體池。在此記憶體池中,某個執行緒可以分派物件,而同時不使用的物件將由共時垃圾回收器進行回收。除非有定義良好的垃圾回收時間,該時間是檢查記憶體使用量的最恰當時間,否則就不應該支持回收使用量閾值。
回收使用量閾值設計用於監視 Java 虛擬機器進行記憶體空間回收工作之後的記憶體使用量。還可以採用與上述監視使用量閾值類似的方法,通過輪詢和閾值通知機制監視回收使用量閾值。
方法摘要 | |
---|---|
MemoryUsage |
getCollectionUsage()
返回 Java 虛擬機器最近回收了此記憶體池中的不使用的物件之後的記憶體使用量。 |
long |
getCollectionUsageThreshold()
返回此記憶體池的回收使用量閾值(以位元組為單位)。 |
long |
getCollectionUsageThresholdCount()
返回 Java 虛擬機器已檢測到記憶體使用量達到或超過回收使用量閾值的次數。 |
String[] |
getMemoryManagerNames()
返回管理此記憶體池的記憶體管理器的名稱。 |
String |
getName()
返回表示此記憶體池的名稱。 |
MemoryUsage |
getPeakUsage()
返回自 Java 虛擬機器啟動以來或自峰值重置以來此記憶體池的峰值記憶體使用量。 |
MemoryType |
getType()
返回此記憶體池的型別。 |
MemoryUsage |
getUsage()
返回此記憶體池的記憶體使用量的估計數。 |
long |
getUsageThreshold()
返回此記憶體池的使用量閾值(以位元組為單位)。 |
long |
getUsageThresholdCount()
返回記憶體使用量超過其閾值的次數。 |
boolean |
isCollectionUsageThresholdExceeded()
測試在 Java 虛擬機器最近一次回收工作之後,此記憶體池的記憶體使用量是否達到或超過了其回收使用量閾值。 |
boolean |
isCollectionUsageThresholdSupported()
測試此記憶體池是否支持回收使用量閾值。 |
boolean |
isUsageThresholdExceeded()
測試此記憶體池的使用量是否達到或超過其使用量閾值。 |
boolean |
isUsageThresholdSupported()
測試此記憶體池是否支持使用量閾值。 |
boolean |
isValid()
測試此記憶體池在 Java 虛擬機器中是否有效。 |
void |
resetPeakUsage()
將此記憶體池的峰值記憶體使用量統計重置為當前記憶體使用量。 |
void |
setCollectionUsageThreshold(long threhsold)
將此記憶體池的回收使用量閾值設置為給定的 threshold 值。 |
void |
setUsageThreshold(long threshold)
如果此記憶體池支持使用量閾值,則將此記憶體池的閾值設置為給定的 threshold 值。 |
方法詳細資訊 |
---|
String getName()
MemoryType getType()
MBeanServer 存取:
MemoryType 的映射型別為 String,值為 MemoryType 的名稱。
MemoryUsage getUsage()
此方法請求 Java 虛擬機器對此記憶體池的當前記憶體使用量進行最佳估算。對於某些記憶體池,此方法可能是開銷很大的操作,需要進行計算以確定估計數。如果是這種情況,實作應該加以註釋。
此方法設計用於監視系統記憶體使用量和檢測低記憶體情況。
MBeanServer 存取:
MemoryUsage 的映射型別為 CompositeData,具有 MemoryUsage
中指定的那些屬性。
MemoryUsage
物件;或者,如果此記憶體池無效,則返回 null。MemoryUsage getPeakUsage()
MBeanServer 存取:
MemoryUsage 的映射型別為 CompositeData,具有 MemoryUsage
中指定的那些屬性。
MemoryUsage
物件;或者,如果此記憶體池無效,則返回 null。void resetPeakUsage()
SecurityException
- 如果存在安全管理器,且調用方不具有 ManagementPermission("control")。boolean isValid()
String[] getMemoryManagerNames()
long getUsageThreshold()
setUsageThreshold
方法更改當前的使用量閾值。
UnsupportedOperationException
- 如果此記憶體池不支持使用量閾值。isUsageThresholdSupported()
void setUsageThreshold(long threshold)
threshold
- 新閾值(以位元組為單位)。必須為非負數。
IllegalArgumentException
- 如果 threshold 為負或大於此記憶體池的最大記憶體量(如果已定義)。
UnsupportedOperationException
- 如果此記憶體池不支持使用量閾值。
SecurityException
- 如果存在安全管理器,且調用方不具有 ManagementPermission("control")。isUsageThresholdSupported()
,
使用量閾值boolean isUsageThresholdExceeded()
UnsupportedOperationException
- 如果此記憶體池不支持使用量閾值。long getUsageThresholdCount()
UnsupportedOperationException
- 如果此記憶體池不支持使用量閾值。boolean isUsageThresholdSupported()
long getCollectionUsageThreshold()
setCollectionUsageThreshold
方法更改回收使用量閾值。
UnsupportedOperationException
- 如果此記憶體池不支持回收使用量閾值。isCollectionUsageThresholdSupported()
void setCollectionUsageThreshold(long threhsold)
如果閾值設置為正數,將啟用此記憶體池中的回收使用量閾值超過檢查。如果設置為零,則將禁用回收使用量閾值超過檢查。
threhsold
- 新的回收使用量閾值(以位元組為單位)。必須為非負數。
IllegalArgumentException
- 如果 threshold 為負或大於此記憶體池的最大記憶體量(如果已定義)。
UnsupportedOperationException
- 如果此記憶體池不支持回收使用量閾值。
SecurityException
- 如果存在安全管理器,且調用方不具有 ManagementPermission("control")。isCollectionUsageThresholdSupported()
,
回收使用量閾值boolean isCollectionUsageThresholdExceeded()
UnsupportedOperationException
- 如果此記憶體池不支持使用量閾值。long getCollectionUsageThresholdCount()
UnsupportedOperationException
- 如果此記憶體池不支持回收使用量閾值。isCollectionUsageThresholdSupported()
MemoryUsage getCollectionUsage()
MBeanServer 存取:
MemoryUsage 的映射型別為 CompositeData,具有 MemoryUsage
中指定的那些屬性。
MemoryUsage
;如果不支持此方法,則返回 null。boolean isCollectionUsageThresholdSupported()
|
JavaTM 2 Platform Standard Ed. 6 |
|||||||||
上一個類別 下一個類別 | 框架 無框架 | |||||||||
摘要: 巢狀 | 欄位 | 建構子 | 方法 | 詳細資訊: 欄位 | 建構子 | 方法 |
版權所有 2008 Sun Microsystems, Inc. 保留所有權利。請遵守GNU General Public License, version 2 only。