[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [equinox-dev] Memory management in Eclipse - and equinox

I fully agree with Ben. 

The org.eclipse.osgi.framework.eventmgr package could be used to manage 
the listener lists and publish event in a bundle safe way.

Also, the Event Admin service with its publish/subscribe model should be 
strongly considered.


BJ Hargrave
Senior Technical Staff Member, IBM
OSGi Fellow and CTO of the OSGi Alliance
hargrave@xxxxxxxxxx
Office: +1 407 849 9117 Mobile: +1 386 848 3788



Benjamin Reed <breed@xxxxxxxxxxxxxxx> 
Sent by: equinox-dev-bounces@xxxxxxxxxxx
2006-01-24 02:29 PM
Please respond to
Equinox development mailing list <equinox-dev@xxxxxxxxxxx>


To
Equinox development mailing list <equinox-dev@xxxxxxxxxxx>
cc

Subject
Re: [equinox-dev] Memory management in Eclipse - and equinox






Have you thought of using the service registry rather than a MemoryManager 
class? You could just have clients register a LowMemoryListener in the 
service registry and have the policy manager interact with the 
LowMemoryListeners it finds in the service registry.

I say this because your implementation relies on the clients to correctly 
unregister themselves if they go away. In effect MemoryManager duplicates 
what the service registry already does, but the service registry also adds 
tracking of plugins as well as security, 

ben

Chris Laffra wrote: 

I have been developing a TPTP memory manager that is implemented as a 
listener framework to broadcast "low memory" events. The proposal is for 
the platform to provide a listener service that allows clients to register 
as a listener to low memory events. 

package org.eclipse.equinox.memory;
 
import java.util.ArrayList;
import java.util.List;
 
/**
 * This class is a placeholder to collect listeners that want to respond 
to low memory events.
 * Some listeners may want to clear a cache. Others may want to close 
editors, entire 
 * perspectives, or other resources that consume memory in some form or 
another. 
 * <p>
 * All this memory manager does is keep a list of listeners and provide a 
way to broadcast 
 * a low-memory event. <p> 
 * An external policy determines when to trigger a broadcast event to be 
sent to the 
 * listeners. 
 * @author Chris Laffra
 * @provisional
 */
public class MemoryManager {
 
 /**
  * Indicates memory is running low at the lowest severity.
  * Listeners are requested to release caches that can easily be 
recomputed. 
  * The java VM is not seriously in problem, but process size is getting 
higher than 
  * is deemed acceptable.
  */
 final public static int LOW = 1;
 
 /**
  * Indicates memory is running low at medium severity. 
  * Listeners are requested to release intermediate build results, complex 
models, etc. 
  * Memory is getting low and may cause operating system level stress, 
such as swapping.
  */
 final public static int SERIOUS = 2;
 
 /**
  * Indicates memory is running low at highest severity.
  * Listeners are requested to do things like close editors and 
perspectives, close 
  * database connections, etc.
  * Restoring these resources and caches constitutes lots of work, but 
memory is so low that
  * drastic measures are required.
  */
 final public static int CRITICAL = 3;
 
 private static List listeners = new ArrayList();
 
 /**
  * Register a listener with the memory manager. After registering, lhe 
listener will 
  * be notified of 
  * situations where memory is running low with an indication of the 
severity.
  * 
  * @param listener  the listener that can clean up memory 
  * 
  * @provisional
  */
 public static synchronized void addLowMemoryListener(LowMemoryListener 
listener) { 
  if (listener == null) {
   throw new NullPointerException();
  }
  if (!listeners.contains(listener)) {
   listeners.add(listener);
  }
 }
 
 /**
  * Remove a low memory listener. 
  * 
  * @param listener the listener to remove
  * 
  * @provisional
  */
 public static synchronized void removeListener(LowMemoryListener 
listener) {
  if (listener == null) {
   throw new NullPointerException(); 
  }
  listeners.remove(listener);
 }
 
 /**
  * Broadcast a low memory event.
  * 
  * @param severity either LOW, SERIOUS, or CRITICAL 
  */ 
 public static void broadcastLowMemory(int severity) {
  if (severity < LOW || severity > CRITICAL) {
   throw new IllegalArgumentException(Integer.toString(severity));
  }
  synchronized (listeners) { 
   for (int n=listeners.size()-1; n>=0; n--) {
    LowMemoryListener listener = (LowMemoryListener) listeners.get(n);
    if (listener != null) {
     listener.memoryIsLow(severity);
    }
   }
  } 
 }
 
 /**
  * @return the current list of listeners
  */
 public static synchronized List getListeners() {
  return new ArrayList(listeners);
 }; 
}
 

The event looks like this: 

package org.eclipse.equinox.memory;
 
/**
 * Extenders of this class listen to low memory events. They typically 
implement a cache
 * (a intermediate representation of some kind that is expensive to 
compute and that 
 * is expected to be computed more than once on a given input).
 * 
 * When memory is low, events will be broadcasted to request cache owners 
to clean up 
 * their caches and hence to free up memory. 
 *
 * @author Chris Laffra
 * @provisional
 */
public abstract class LowMemoryListener {
 
 /**
  * Return a user-readable description of the listener, for debugging 
purposes.
  */
 public abstract String getDescription(); 
 
 /**
  * Return the number of items in the cache managed by the listener
  * 
  * @provisional
  */
 public abstract int getCount();
 
 /**
  * Return an estimate of the total memory (in bytes) consumed by the 
cache managed 
  * by the listener. 
  * Return -1 when the size is unknown.
  * 
  * @provisional
  */
 public abstract long getSize();
 
 /**
  * Inform the listener that memory is low, indicating severity.
  * severity is one of LOW, SERIOUS, CRITICAL 
  * 
  * @provisional
  */
 public abstract void memoryIsLow(int severity);
 
}
 

As you can see the above contains no policy implementation that triggers 
the broadcasting of the "low memory" events. 
We expect that code to be application-specific and may requires native 
code to collect statistics on available 
physical memory, current consumption, page fault rate, CPU, etc.

As it stands, the above listener is committed to TPTP HEAD and will be 
included in a build this week. 

Would the equinox project be interested into including this API into 
Platform core so that more plugins up the stack 
can benefit from the api, without needing to buy into TPTP?

I added a screendump of a UI monitor that is included in TPTP that 
monitors the current caches. 
As you can see, I added 6 caches that I found in JDT as an example. When 
users press the garbage can, 
the "low memory CRITICAL" event is broadcasted and the JDT caches react by 
flushing themselves.
As an experiment, we send out timed "low memory LOW" events.
 
Your feedback is appreciated,

Chris Laffra 


_______________________________________________
equinox-dev mailing list
equinox-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/equinox-dev
 
_______________________________________________
equinox-dev mailing list
equinox-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/equinox-dev