/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package flash.tools.debugger.concrete; /** * This cache directly manages the creation/destruction of DMessages * by allowing DMessages to be re-used. * * It has been observed that the Player send a tremendous number of * small (< 8Byte of data) messages and that by allocating a fixed * number of these, and then re-using them, we can assist the garbage * collector greatly. * * The cache is arranged as an array whereby DMessages with 'index' * number of bytes for data are housed. It is asssumed that at * any moment in time only one DMessage will be required and thus * this technique works. If DMessages are to be stored for * later processing (implying that many will exist at any moment) * then we need to implement a more sophisticated cache (probably * storing a Vector of DMessages at each index). * * Very large DMessages are currently not cached. * * This is class is a singleton. */ public class DMessageCache { public static final int MAX_CACHED_DATA_SIZE = 128; /* should consume around 4n + n(n+1)/2 bytes */ /* our cache */ static DMessage[] m_cache = new DMessage[MAX_CACHED_DATA_SIZE]; /** * Obtain a DMessage from the cache if possible, otherwise make one for me. */ public static DMessage alloc(int size) { DMessage msg; int index = size2Index(size); /** * We see if this could possibly be found in our cache, * if so, then see if there is one for us to use, * otherwise create a new one */ if (index < 0) msg = new DMessage(size); else if (m_cache[index] == null) msg = new DMessage(size); else { msg = m_cache[index]; m_cache[index] = null; } // System.out.println("msgsize="+size+uft()); return msg; } private static String uft() { Runtime rt = Runtime.getRuntime(); long free = rt.freeMemory(), total = rt.totalMemory(), used = total - free; // long max = rt.maxMemory(); java.text.NumberFormat nf = java.text.NumberFormat.getInstance() ; // System.out.println("used: "+nf.format(used)+" free: "+nf.format(free)+" total: "+nf.format(total)+" max: "+nf.format(max)); return ", used "+nf.format(used)+", free "+nf.format(free)+", total "+nf.format(total); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } /** * Put a DMessage into the cache for reuse */ public static void free(DMessage msg) { int index = size2Index(msg.getSize()); msg.clear(); /* clear stuff up for re-use */ /** * If it is too big we don't store cache, assuming * the GC can do a better job than us at reusing the memory, * Otherwise we put it in our cache */ if (index < 0) ; else if (m_cache[index] != null) ; /* bad => need to use a Vector in the array to house multiple DMessages */ else m_cache[index] = msg; } public static int size2Index(int size) { return ((size < MAX_CACHED_DATA_SIZE) ? size : -1); } // public static int size2Index(int size) { return -1; } }