KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > source > util > LowMemoryNotifier


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.java.source.util;
21
22 import java.lang.management.ManagementFactory JavaDoc;
23 import java.lang.management.MemoryMXBean JavaDoc;
24 import java.lang.management.MemoryNotificationInfo JavaDoc;
25 import java.lang.management.MemoryPoolMXBean JavaDoc;
26 import java.lang.management.MemoryType JavaDoc;
27 import java.lang.management.MemoryUsage JavaDoc;
28 import java.util.ArrayList JavaDoc;
29 import java.util.List JavaDoc;
30 import javax.management.ListenerNotFoundException JavaDoc;
31 import javax.management.Notification JavaDoc;
32 import javax.management.NotificationEmitter JavaDoc;
33 import javax.management.NotificationListener JavaDoc;
34 import org.openide.ErrorManager;
35
36 /**
37  *
38  * @author Tomas Zezula
39  */

40 public class LowMemoryNotifier {
41     
42     private static final float DEFAULT_HEAP_LIMIT = 0.9f;
43     
44     private static LowMemoryNotifier instance;
45     
46     private final NotificationListener JavaDoc notificationListener = new Listener JavaDoc ();
47     private final List JavaDoc<LowMemoryListener> listeners;
48     private MemoryPoolMXBean JavaDoc pool;
49     private MemoryPoolMXBean JavaDoc cachedPool; //Only initJMX may use this field!
50
private float heapLimit;
51     
52     
53     /** Creates a new instance of LowMemoryNotifier */
54     private LowMemoryNotifier() {
55         this.heapLimit = DEFAULT_HEAP_LIMIT;
56         this.listeners = new ArrayList JavaDoc<LowMemoryListener> ();
57     }
58     
59     
60     float getHeapLimit () {
61         return this.heapLimit;
62     }
63     
64     void setHeapLimit (float heapLimit) {
65         this.heapLimit = heapLimit;
66         synchronized (this) {
67             if (this.pool != null) {
68                 MemoryUsage JavaDoc mu = pool.getUsage();
69                 this.pool.setUsageThreshold ((long)(mu.getMax() * heapLimit));
70             }
71         }
72     }
73     
74     
75     public synchronized void addLowMemoryListener (final LowMemoryListener listener) {
76         assert listener != null;
77         if (this.pool == null) {
78             this.pool = initJMX ();
79         }
80         assert this.pool != null;
81         final MemoryUsage JavaDoc usage = this.pool.getUsage();
82         assert usage != null : String.format("Pool %s returned null MemoryUsage, Valid: %s\n",this.pool.getName(),this.pool.isValid() ? Boolean.TRUE : Boolean.FALSE);
83         if (usage != null && usage.getUsed() >= this.pool.getUsageThreshold()) {
84             listener.lowMemory (new LowMemoryEvent (this, this.pool));
85         }
86         this.listeners.add (listener);
87     }
88     
89     public synchronized void removeLowMemoryListener (final LowMemoryListener listener) {
90         assert listener != null;
91         this.listeners.remove (listener);
92         if (this.listeners.isEmpty() && this.pool != null) {
93             finishJMX (this.pool);
94             this.pool = null;
95         }
96     }
97     
98     private void fireLowMemory () {
99         LowMemoryListener[] _listeners;
100         MemoryPoolMXBean JavaDoc _pool;
101         synchronized (this) {
102             _listeners = this.listeners.toArray(new LowMemoryListener[this.listeners.size()]);
103             _pool = this.pool;
104         }
105         if (_listeners.length > 0) {
106             assert _pool != null;
107             final LowMemoryEvent event = new LowMemoryEvent (this, _pool);
108             for (LowMemoryListener l : _listeners) {
109                 l.lowMemory(event);
110             }
111         }
112     }
113     
114     private MemoryPoolMXBean JavaDoc initJMX () {
115         List JavaDoc<MemoryPoolMXBean JavaDoc> pools = null;
116         if (this.cachedPool == null || !this.cachedPool.isValid()) {
117             pools = ManagementFactory.getMemoryPoolMXBeans();
118             for (MemoryPoolMXBean JavaDoc pool : pools) {
119                 if (pool.getType() == MemoryType.HEAP && pool.isUsageThresholdSupported()) { //NOI18N
120
this.cachedPool = pool;
121                     break;
122                 }
123             }
124         }
125         assert this.cachedPool != null : dumpMemoryPoolMXBean (pools);
126         if (this.cachedPool != null) {
127             MemoryUsage JavaDoc mu = this.cachedPool.getUsage();
128             this.cachedPool.setUsageThreshold((long)(mu.getMax() * heapLimit));
129             MemoryMXBean JavaDoc mbean = ManagementFactory.getMemoryMXBean();
130             ((NotificationEmitter JavaDoc)mbean).addNotificationListener(this.notificationListener,null,null);
131         }
132         return this.cachedPool;
133     }
134     
135     private void finishJMX (final MemoryPoolMXBean JavaDoc pool) {
136         assert pool != null;
137         try {
138             MemoryMXBean JavaDoc mbean = ManagementFactory.getMemoryMXBean();
139             ((NotificationEmitter JavaDoc)mbean).removeNotificationListener(this.notificationListener);
140         } catch (ListenerNotFoundException JavaDoc e) {
141             ErrorManager.getDefault().notify(e);
142         }
143         pool.setUsageThreshold(0);
144     }
145     
146     private class Listener implements NotificationListener JavaDoc {
147         public void handleNotification(Notification JavaDoc notification, Object JavaDoc handback) {
148             final String JavaDoc notificationType = notification.getType();
149             if (notificationType.equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)) {
150                 fireLowMemory ();
151             }
152         }
153         
154     }
155     
156     private static String JavaDoc dumpMemoryPoolMXBean (List JavaDoc<MemoryPoolMXBean JavaDoc> pools) {
157         StringBuilder JavaDoc sb = new StringBuilder JavaDoc ();
158         for (MemoryPoolMXBean JavaDoc pool : pools) {
159             sb.append(String.format("Pool: %s Type: %s TresholdSupported: %s\n", pool.getName(), pool.getType(), pool.isUsageThresholdSupported() ? Boolean.TRUE : Boolean.FALSE));
160         }
161         sb.append('\n');
162         return sb.toString();
163     }
164     
165     public static synchronized LowMemoryNotifier getDefault () {
166         if (instance == null) {
167             instance = new LowMemoryNotifier ();
168         }
169         return instance;
170     }
171     
172 }
173
Popular Tags