⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gclisteningdelaycache.java

📁 Java的面向对象数据库系统的源代码
💻 JAVA
字号:
// You can redistribute this software and/or modify it under the terms of// the Ozone Core License version 1 published by ozone-db.org.//// Copyright (C) 2003-@year@, Leo Mekenkamp. All rights reserved.//// $Id: GcListeningDelayCache.java,v 1.3.2.1 2004/03/28 16:40:04 per_nyfelt Exp $package org.ozoneDB.core.storage;import java.lang.ref.ReferenceQueue;import java.lang.ref.WeakReference;import java.util.Properties;import java.util.logging.Level;import java.util.logging.Logger;import org.ozoneDB.core.ConfigurationException;import org.ozoneDB.core.storage.DelayCache.TimedEntry;/** * @author <a href="mailto:leoATmekenkampD0Tcom">Leo Mekenkamp (mind the anti sp@m)</a> * @version $Id: GcListeningDelayCache.java,v 1.3.2.1 2004/03/28 16:40:04 per_nyfelt Exp $ */public class GcListeningDelayCache extends DelayCache {        private static Logger log = Logger.getLogger(GcListeningDelayCache.class.getName());        public static final PropertyInfo HIGHTHRESHOLD = new PropertyInfo(        ".highThreshold",        "int",        "10000000",        "when free memory falls below this threshold this cache will start throwing out elements",        new String[] {"10000", "50000000"}    );    public static final PropertyInfo LOWTHRESHOLD = new PropertyInfo(        ".lowThreshold",        "int",        "-1000000",        "when free memory falls below this threshold this cache will throw out all elements (may be < 0)",        new String[] {"1000", "-500000"}    );    /**     * gets cleared every time the jvm gc runs     */    private WeakReference gcIndicator;        private ReferenceQueue gcQueue = new ReferenceQueue();    private Thread gcIndicatorThread = new GcIndicatorThread();        private long lowThreshold;    private long highThreshold;        public GcListeningDelayCache(Properties properties, String prefix) {        super(properties, prefix);        gcIndicatorThread.start();        try {            lowThreshold = Integer.parseInt(properties.getProperty(prefix + LOWTHRESHOLD.getKey(), LOWTHRESHOLD.getDefaultValue()));            log.config(getPrefix() + " using a low threshold of " + lowThreshold);            highThreshold = Integer.parseInt(properties.getProperty(prefix + HIGHTHRESHOLD.getKey(), HIGHTHRESHOLD.getDefaultValue()));            log.config(getPrefix() + " using a high threshold of " + highThreshold);        } catch (NumberFormatException e) {            throw new ConfigurationException(e);        }    }        /**     * Creates an object that is only weakly referenced. There is a 1 on 1     * correspondance between this weak reference getting enqueued and a     * jvm gc run     */    private final void resetGcIndicator() {        gcIndicator = new WeakReference(new Object(), gcQueue);    }        private void ourGC() {        synchronized(getSynchronizer()) {            if (size() > 0) {                long freeMemory = Runtime.getRuntime().freeMemory();                if (freeMemory < getHighThreshold()) {                    // y == ax + b                    // 1 == a * low + b                    // 0 == a * high + b                    //                     // b == -a * high                    //                    // 1 == a * low - a * high                    //                    // a == 1 / (low - high)                    //                    // b == -high / (low - high)                    //                    // y == x / (low - high) - high / (low - high)                    // y == (x - high) / (low - high)                    float clearRatio = (float) (freeMemory - getHighThreshold()) / (float) (getLowThreshold() - getHighThreshold());                    if (clearRatio > 0) {                        if (clearRatio > 1) {                            clearRatio = 1;                        }                        if (log.isLoggable(Level.FINE)) log.fine("removing " + clearRatio + " from cache");                        int numToClear = (int) (size() * clearRatio);                        if (numToClear < 1) {                            numToClear = 1;                        }                        for (;numToClear > 0; numToClear--) {                            TimedEntry last = (TimedEntry) getEntries().last();                            if (getTrimHandler() != null) {                                getTrimHandler().trimming(last.key, last.value);                            }                            getEntries().remove(last);                            getKeysToEntries().remove(last.key);                        }                    }                }            }        }    }        /**     * value in range <max(0,lowThreshold), 1] indicating when caches should     * start throwing away entries.     */    public void setHighThreshold(long highThreshold) {        synchronized(getSynchronizer()) {            if (highThreshold <= getLowThreshold()) {                String msg = "could not set highThreshold to " + highThreshold + "; must be > lowThreshold (" + getLowThreshold() + ")";                log.severe(msg);                throw new IllegalArgumentException(msg);            }            this.highThreshold = highThreshold;        }    }        /**     * value in range <0, min(1,highThreshold)] indicating when cache should     * throw away all its entries.     */    public void setLowThreshold(long lowThreshold) {        synchronized(getSynchronizer()) {            if (lowThreshold < 0 || lowThreshold >= getHighThreshold()) {                String msg = "could not set lowThreshold to " + lowThreshold + "; must be >= 0 and <= highThreshold (" + getHighThreshold() + ")";                log.severe(msg);                throw new IllegalArgumentException(msg);            }            this.lowThreshold = lowThreshold;        }    }        public long getHighThreshold() {        synchronized(getSynchronizer()) {            return highThreshold;        }    }        public synchronized long getLowThreshold() {        synchronized(getSynchronizer()) {            return lowThreshold;        }    }        /**     * Is woken up every time the gc has completed a run, or is in the process     * of a run. The javadocs are a bit sketchy on this. Empirical data seems     * to suggest the first.     */    private class GcIndicatorThread extends Thread {                GcIndicatorThread() {            super(Thread.currentThread().getThreadGroup(), "gc indicator");            setDaemon(true);            // setting priority to high to lessen the chance that another            // thread does a lot of object creating during our run()            setPriority(Thread.MAX_PRIORITY - 1);        }                public void run() {            for (;;) {                try {                    resetGcIndicator();                                        // only interested in 'when', not 'what', no 'Reference ref ='                    gcQueue.remove();                    if (log.isLoggable(Level.FINE)) {                        Runtime runtime = Runtime.getRuntime();                        log.fine("gc has kicked in (free mem: " + runtime.freeMemory() + ", total mem: " + runtime.totalMemory());                    }                    ourGC();                } catch (InterruptedException ignore) {                }            }        }            }            // DEBUG AND BUGTEST CODE ONLY FOLLOWING; not needed for normal operation        static class Item {        byte[] filling = new byte[100];        private Object key;                Item(Object key) {            this.key = key;        }                public String toString() {            return key.toString();        }            }        public static void main(String[] args) {        Properties properties = new Properties();        String prefix = "dbg";        properties.setProperty(prefix + LOWTHRESHOLD.getKey(), "-32000000");        properties.setProperty(prefix + HIGHTHRESHOLD.getKey(), "1000000");        properties.setProperty(prefix + DELAY.getKey(), "2000");        GcListeningDelayCache cache = new GcListeningDelayCache(properties, prefix);                for (int i = 0; ; i++ ) {            Object key = new Integer(i);            Item item = new Item(key);            //            System.out.println("creating " + key + ", free: " + Runtime.getRuntime().freeMemory());            cache.put(key, item);            if (i > 10) {                //                System.out.println("get(10): " + cache.get(new Integer(10)));            }                        if (cache.size() % 100 == 0) {                System.out.println("references in map: " + cache.size() + ", free: " + Runtime.getRuntime().freeMemory());            }        }        //        System.out.println("completed sucessfully");    }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -