X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics%2Fsrc%2Forg%2Fsimantics%2FMemoryWarningSystem.java;h=910b1fff3917cbd174b1b0a2fed6c2bc90f368aa;hb=48bb50bb6640506d1f150ca8e4fa5a6e878464be;hp=1a46805a9bed81ca53826de05656c5f7d398453f;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics/src/org/simantics/MemoryWarningSystem.java b/bundles/org.simantics/src/org/simantics/MemoryWarningSystem.java index 1a46805a9..910b1fff3 100644 --- a/bundles/org.simantics/src/org/simantics/MemoryWarningSystem.java +++ b/bundles/org.simantics/src/org/simantics/MemoryWarningSystem.java @@ -1,130 +1,130 @@ -package org.simantics; - -import java.lang.management.ManagementFactory; -import java.lang.management.MemoryPoolMXBean; -import java.lang.management.MemoryType; -import java.util.Collection; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -/** - * This memory warning system will call the listener when we exceed the - * percentage of available memory specified. There should only be one instance - * of this object created, since the usage threshold can only be set to one - * number. - * - * ( adapted from http://www.javaspecialists.eu/archive/Issue092.html ) - * - * @author Antti Villberg - */ -public class MemoryWarningSystem { - - public interface MemoryWarningListener { - void memoryLow(long usedMemory); - } - - private final Collection listeners = new CopyOnWriteArrayList(); - - private static final MemoryPoolMXBean tenuredGenPool = findTenuredGenPool(); - - private double percentage = 1.0; - - private ScheduledFuture future; - - private boolean disposed = false; - - public MemoryWarningSystem(int amount, TimeUnit unit) { -// MemoryMXBean mbean = ManagementFactory.getMemoryMXBean(); -// NotificationEmitter emitter = (NotificationEmitter) mbean; -// emitter.addNotificationListener(new NotificationListener() { -// @Override -// public void handleNotification(Notification n, Object hb) { -// if (n.getType().equals( -// MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)) { -// if(!check()) { -// long used = getUsed(); -// for (MemoryWarningListener listener : listeners) { -// listener.memoryLow(used); -// } -// } -// setPercentageUsageThreshold(percentage); -// } -// } -// }, null, null); - - future = Simantics.scheduleAtFixedRate(new Runnable() { - - @Override - public void run() { - if(!disposed && !check()) { - long bytes = get(); - for (MemoryWarningListener listener : listeners) { - listener.memoryLow(bytes); - } - } - } - - }, 0, amount, unit); - - } - - public long get() { - return tenuredGenPool.getUsage().getUsed(); - } - - public boolean check() { - long max = Runtime.getRuntime().maxMemory(); - long usedMemory = get(); - long threshold = (long)(max * percentage); - return usedMemory < threshold; - } - - public long getUsed() { - return tenuredGenPool.getUsage().getUsed(); - } - - public boolean addListener(MemoryWarningListener listener) { - return listeners.add(listener); - } - - public boolean removeListener(MemoryWarningListener listener) { - return listeners.remove(listener); - } - - public void setPercentageUsageThreshold(double percentage) { - if (percentage <= 0.0 || percentage > 1.0) { - throw new IllegalArgumentException("Percentage not in range"); - } - this.percentage = percentage; -// long maxMemory = Runtime.getRuntime().maxMemory(); -// long warningThreshold = (long) (maxMemory * percentage); -// tenuredGenPool.setUsageThreshold(0); -// tenuredGenPool.setUsageThreshold(warningThreshold); - } - - /** - * Tenured Space Pool can be determined by it being of type HEAP and by it - * being possible to set the usage threshold. - */ - private static MemoryPoolMXBean findTenuredGenPool() { - for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) { - // I don't know whether this approach is better, or whether - // we should rather check for the pool name "Tenured Gen"? - if (pool.getType() == MemoryType.HEAP - && pool.isUsageThresholdSupported()) { - return pool; - } - } - throw new IllegalStateException("Could not find tenured space"); - } - - public void dispose() { - if (!disposed) { - disposed = true; - future.cancel(false); - listeners.clear(); - } - } - +package org.simantics; + +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryPoolMXBean; +import java.lang.management.MemoryType; +import java.util.Collection; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +/** + * This memory warning system will call the listener when we exceed the + * percentage of available memory specified. There should only be one instance + * of this object created, since the usage threshold can only be set to one + * number. + * + * ( adapted from http://www.javaspecialists.eu/archive/Issue092.html ) + * + * @author Antti Villberg + */ +public class MemoryWarningSystem { + + public interface MemoryWarningListener { + void memoryLow(long usedMemory); + } + + private final Collection listeners = new CopyOnWriteArrayList(); + + private static final MemoryPoolMXBean tenuredGenPool = findTenuredGenPool(); + + private double percentage = 1.0; + + private ScheduledFuture future; + + private boolean disposed = false; + + public MemoryWarningSystem(int amount, TimeUnit unit) { +// MemoryMXBean mbean = ManagementFactory.getMemoryMXBean(); +// NotificationEmitter emitter = (NotificationEmitter) mbean; +// emitter.addNotificationListener(new NotificationListener() { +// @Override +// public void handleNotification(Notification n, Object hb) { +// if (n.getType().equals( +// MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)) { +// if(!check()) { +// long used = getUsed(); +// for (MemoryWarningListener listener : listeners) { +// listener.memoryLow(used); +// } +// } +// setPercentageUsageThreshold(percentage); +// } +// } +// }, null, null); + + future = Simantics.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + if(!disposed && !check()) { + long bytes = get(); + for (MemoryWarningListener listener : listeners) { + listener.memoryLow(bytes); + } + } + } + + }, 0, amount, unit); + + } + + public long get() { + return tenuredGenPool.getUsage().getUsed(); + } + + public boolean check() { + long max = Runtime.getRuntime().maxMemory(); + long usedMemory = get(); + long threshold = (long)(max * percentage); + return usedMemory < threshold; + } + + public long getUsed() { + return tenuredGenPool.getUsage().getUsed(); + } + + public boolean addListener(MemoryWarningListener listener) { + return listeners.add(listener); + } + + public boolean removeListener(MemoryWarningListener listener) { + return listeners.remove(listener); + } + + public void setPercentageUsageThreshold(double percentage) { + if (percentage <= 0.0 || percentage > 1.0) { + throw new IllegalArgumentException("Percentage not in range"); + } + this.percentage = percentage; +// long maxMemory = Runtime.getRuntime().maxMemory(); +// long warningThreshold = (long) (maxMemory * percentage); +// tenuredGenPool.setUsageThreshold(0); +// tenuredGenPool.setUsageThreshold(warningThreshold); + } + + /** + * Tenured Space Pool can be determined by it being of type HEAP and by it + * being possible to set the usage threshold. + */ + private static MemoryPoolMXBean findTenuredGenPool() { + for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) { + // I don't know whether this approach is better, or whether + // we should rather check for the pool name "Tenured Gen"? + if (pool.getType() == MemoryType.HEAP + && pool.isUsageThresholdSupported()) { + return pool; + } + } + throw new IllegalStateException("Could not find tenured space"); + } + + public void dispose() { + if (!disposed) { + disposed = true; + future.cancel(false); + listeners.clear(); + } + } + } \ No newline at end of file