blob: 319235b907a545901be484dd84eabfd99ce0ea23 [file] [log] [blame]
/*
* 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; }
}