KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > retouche > 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.retouche.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  * This file is originally from Retouche, the Java Support
38  * infrastructure in NetBeans. I have modified the file as little
39  * as possible to make merging Retouche fixes back as simple as
40  * possible.
41  *
42  *
43  * @author tom
44  */

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