001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.lang.management;
019:
020: import java.lang.management.MemoryNotificationInfo;
021: import java.lang.management.MemoryUsage;
022:
023: import javax.management.Notification;
024:
025: /**
026: * A thread that monitors and dispatches memory usage notifications from an
027: * internal queue.
028: *
029: * @since 1.5
030: */
031: class MemoryNotificationThread extends Thread {
032:
033: private MemoryMXBeanImpl memBean;
034:
035: private MemoryPoolMXBeanImpl memPool;
036:
037: int internalID;
038:
039: /**
040: * Basic constructor
041: *
042: * @param mem
043: * The memory bean to send notifications through
044: * @param myPool
045: * The memory pool bean we are sending notifications on behalf of
046: * @param id
047: * The internal ID of the notification queue being monitored
048: */
049: MemoryNotificationThread(MemoryMXBeanImpl mem,
050: MemoryPoolMXBeanImpl myPool, int id) {
051: memBean = mem;
052: memPool = myPool;
053: internalID = id;
054: }
055:
056: /**
057: * Register a shutdown handler that will signal this thread to terminate,
058: * then enter the native that services an internal notification queue.
059: */
060: public void run() {
061: Thread myShutdownNotifier = new MemoryNotificationThreadShutdown(
062: this );
063: try {
064: Runtime.getRuntime().addShutdownHook(myShutdownNotifier);
065: } catch (IllegalStateException e) {
066: /*
067: * if by chance we are already shutting down when we try to register
068: * the shutdown hook, allow this thread to terminate silently
069: */
070: return;
071: }
072: processNotificationLoop(internalID);
073: }
074:
075: /**
076: * Process notifications on an internal VM queue until a shutdown request is
077: * received.
078: *
079: * @param internalID
080: * The internal ID of the queue to service
081: */
082: private native void processNotificationLoop(int internalID);
083:
084: /**
085: * A helper method called from within the native
086: * {@link #processNotificationLoop(int)} method to construct and dispatch
087: * notification objects.
088: *
089: * @param min
090: * the initial amount in bytes of memory that can be allocated by
091: * this virtual machine
092: * @param used
093: * the number of bytes currently used for memory
094: * @param committed
095: * the number of bytes of committed memory
096: * @param max
097: * the maximum number of bytes that can be used for memory
098: * management purposes
099: * @param count
100: * the number of times that the memory usage of the memory pool
101: * in question has met or exceeded the relevant threshold
102: * @param sequenceNumber
103: * the sequence identifier of the current notification
104: * @param isCollectionUsageNotification
105: * a <code>boolean</code> indication of whether or not the new
106: * notification is as a result of the collection threshold being
107: * exceeded. If this value is <code>false</code> then the
108: * implication is that a memory threshold has been exceeded.
109: */
110: @SuppressWarnings("unused")
111: // IMPORTANT: for use by VM
112: private void dispatchNotificationHelper(long min, long used,
113: long committed, long max, long count, long sequenceNumber,
114: boolean isCollectionUsageNotification) {
115: MemoryNotificationInfo info = new MemoryNotificationInfo(
116: memPool.getName(), new MemoryUsage(min, used,
117: committed, max), count);
118: Notification n = new Notification(
119: isCollectionUsageNotification ? MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED
120: : MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED,
121: "java.lang:type=Memory", sequenceNumber);
122: n.setUserData(ManagementUtils
123: .toMemoryNotificationInfoCompositeData(info));
124: memBean.sendNotification(n);
125: }
126: }
|