📄 directbytebufferpool.java
字号:
bytesToFree += buffSizes[i];
}
}
//reduce max size for next round
maxPoolSize--;
}
//free buffers from the pools
pos = 0;
it = buffersMap.values().iterator();
while (it.hasNext()) {
//for each pool
ArrayList bufferPool = (ArrayList)it.next();
synchronized( bufferPool ) {
int size = bufferPool.size();
//remove the buffers from the end
for (int i=(size - 1); i >= (size - numToFree[pos]); i--) {
bufferPool.remove(i);
}
}
pos++;
}
runGarbageCollection();
}
private long bytesFree() {
long bytesUsed = 0;
synchronized( poolsLock ) {
//count up total bytes used by free buffers
Iterator it = buffersMap.keySet().iterator();
while (it.hasNext()) {
Integer keyVal = (Integer)it.next();
ArrayList bufferPool = (ArrayList)buffersMap.get(keyVal);
bytesUsed += keyVal.intValue() * bufferPool.size();
}
}
return bytesUsed;
}
/*
private final HashMap in_use_counts = new HashMap();
private void addInUse( int size ) {
Integer key = new Integer( size );
synchronized( in_use_counts ) {
Integer count = (Integer)in_use_counts.get( key );
if( count == null ) count = new Integer( 1 );
else count = new Integer( count.intValue() + 1 );
in_use_counts.put( key, count );
}
}
private void remInUse( int size ) {
Integer key = new Integer( size );
synchronized( in_use_counts ) {
Integer count = (Integer)in_use_counts.get( key );
if( count == null ) System.out.println("count = null");
if( count.intValue() == 0 ) System.out.println("count = 0");
in_use_counts.put( key, new Integer( count.intValue() - 1 ) );
}
}
private void printInUse() {
synchronized( in_use_counts ) {
for( Iterator i = in_use_counts.keySet().iterator(); i.hasNext(); ) {
Integer key = (Integer)i.next();
int count = ((Integer)in_use_counts.get( key )).intValue();
int size = key.intValue();
if( count > 0 ) {
if( size < 1024 ) System.out.print("[" +size+ " x " +count+ "] ");
else System.out.print("[" +size/1024+ "K x " +count+ "] ");
}
}
System.out.println();
}
}
*/
private void
printInUse(
boolean verbose )
{
if ( DEBUG_PRINT_MEM ){
CacheFileManager cm = null;
try{
cm = CacheFileManagerFactory.getSingleton();
}catch( Throwable e ){
Debug.printStackTrace( e );
}
synchronized( handed_out ){
Iterator it = handed_out.values().iterator();
Map cap_map = new TreeMap();
Map alloc_map = new TreeMap();
while( it.hasNext()){
DirectByteBuffer db = (DirectByteBuffer)it.next();
if ( verbose ){
String trace = db.getTraceString();
if ( trace != null ){
System.out.println( trace );
}
}
Integer cap = new Integer( db.getBufferInternal().capacity());
Byte alloc = new Byte( db.getAllocator());
myInteger c = (myInteger)cap_map.get(cap);
if ( c == null ){
c = new myInteger();
cap_map.put( cap, c );
}
c.value++;
myInteger a = (myInteger)alloc_map.get(alloc);
if ( a == null ){
a = new myInteger();
alloc_map.put( alloc, a );
}
a.value++;
}
it = cap_map.keySet().iterator();
while( it.hasNext()){
Integer key = (Integer)it.next();
myInteger count = (myInteger)cap_map.get( key );
if( key.intValue() < 1024 ){
System.out.print("[" +key.intValue()+ " x " +count.value+ "] ");
}else{
System.out.print("[" +key.intValue()/1024+ "K x " +count.value+ "] ");
}
}
System.out.println();
it = alloc_map.keySet().iterator();
while( it.hasNext()){
Byte key = (Byte)it.next();
myInteger count = (myInteger)alloc_map.get( key );
System.out.print("[" + DirectByteBuffer.AL_DESCS[key.intValue()]+ " x " +count.value+ "] ");
}
if ( cm != null ){
CacheFileManagerStats stats = cm.getStats();
System.out.print( " - Cache: " );
System.out.print( "sz=" + stats.getSize());
System.out.print( ",us=" + stats.getUsedSize());
System.out.print( ",cw=" + stats.getBytesWrittenToCache());
System.out.print( ",cr=" + stats.getBytesReadFromCache());
System.out.print( ",fw=" + stats.getBytesWrittenToFile());
System.out.print( ",fr=" + stats.getBytesReadFromFile());
}
System.out.println();
if ( DEBUG_HANDOUT_SIZES ){
it = size_counts.entrySet().iterator();
String str = "";
while( it.hasNext()){
Map.Entry entry = (Map.Entry)it.next();
str += (str.length()==0?"":",") + entry.getKey() + "=" + entry.getValue();
}
System.out.println( str );
}
String str = "";
for (int i=0;i<slice_entries.length;i++){
boolean[] allocs = slice_allocs[i];
int alloc_count = 0;
for (int j=0;j<allocs.length;j++){
if( allocs[j]){
alloc_count++;
}
}
str += (i==0?"":",") + "["+SLICE_ENTRY_SIZES[i]+"]f=" +slice_entries[i].size()+",a=" + (alloc_count*SLICE_ENTRY_ALLOC_SIZES[i]) + ",u=" +slice_use_count[i];
}
System.out.println( "slices: " + str );
}
}
}
// Slice buffer management
protected DirectByteBuffer
getSliceBuffer(
byte _allocator,
int _length )
{
int slice_index = getSliceIndex( _length );
List my_slice_entries = slice_entries[slice_index];
synchronized( my_slice_entries ){
boolean[] my_allocs = slice_allocs[slice_index];
sliceBuffer sb = null;
if ( my_slice_entries.size() > 0 ){
sb = (sliceBuffer)my_slice_entries.remove(0);
slice_use_count[slice_index]++;
}else{
// find a free slot
short slot = -1;
for (short i=0;i<my_allocs.length;i++){
if( !my_allocs[i]){
slot = i;
break;
}
}
if ( slot != -1 ){
short slice_entry_size = SLICE_ENTRY_SIZES[slice_index];
short slice_entry_count = SLICE_ENTRY_ALLOC_SIZES[slice_index];
ByteBuffer chunk = ByteBuffer.allocateDirect( slice_entry_size*slice_entry_count );
my_allocs[slot] = true;
for (short i=0;i<slice_entry_count;i++){
chunk.limit((i+1)*slice_entry_size);
chunk.position(i*slice_entry_size);
ByteBuffer slice = chunk.slice();
sliceBuffer new_buffer = new sliceBuffer( slice, slot, i );
if ( i == 0 ){
sb = new_buffer;
slice_use_count[slice_index]++;
}else{
my_slice_entries.add( new_buffer );
}
}
}else{
if ( !slice_alloc_fails[slice_index] ){
slice_alloc_fails[slice_index] = true;
Debug.out( "Run out of slice space for '" + SLICE_ENTRY_SIZES[slice_index] + ", reverting to normal allocation" );
}
ByteBuffer buff = ByteBuffer.allocate( _length );
return( new DirectByteBuffer( _allocator, buff, this ));
}
}
sliceDBB dbb = new sliceDBB( _allocator, sb );
return( dbb );
}
}
protected void
freeSliceBuffer(
DirectByteBuffer ddb )
{
if ( ddb instanceof sliceDBB ){
int slice_index = getSliceIndex( ddb.getBufferInternal().capacity());
List my_slice_entries = slice_entries[slice_index];
synchronized( my_slice_entries ){
my_slice_entries.add( 0, ((sliceDBB)ddb).getSliceBuffer());
}
}
}
protected void
compactSlices()
{
// we don't maintain the buffers in sorted order as this is too costly. however, we
// always allocate and free from the start of the free list, so unused buffer space
// will be at the end of the list. we periodically sort this list into allocate block
// order so that if an entire block isn't used for one compaction cycle all of
// its elements will end up together, if you see what I mean :P
// when we find an entire block is unused then we just drop them from the list to
// permit them (and the underlying block) to be garbage collected
for (int i=0;i<slice_entries.length;i++){
int entries_per_alloc = SLICE_ENTRY_ALLOC_SIZES[i];
List l = slice_entries[i];
// no point in trying gc if not enough entries
if ( l.size() >= entries_per_alloc ){
synchronized( l ){
Collections.sort( l,
new Comparator()
{
public int
compare(
Object o1,
Object o2 )
{
sliceBuffer sb1 = (sliceBuffer)o1;
sliceBuffer sb2 = (sliceBuffer)o2;
int res = sb1.getAllocID() - sb2.getAllocID();
if ( res == 0 ){
res = sb1.getSliceID() - sb2.getSliceID();
}
return( res );
}
});
boolean[] allocs = slice_allocs[i];
Iterator it = l.iterator();
int current_alloc = -1;
int entry_count = 0;
boolean freed_one = false;
while( it.hasNext()){
sliceBuffer sb = (sliceBuffer)it.next();
int aid = sb.getAllocID();
if ( aid != current_alloc ){
if ( entry_count == entries_per_alloc ){
// System.out.println( "CompactSlices[" + SLICE_ENTRY_SIZES[i]+"] freeing " + aid );
freed_one = true;
allocs[aid] = false;
}
current_alloc = aid;
entry_count = 1;
}else{
entry_count++;
}
}
if ( entry_count == entries_per_alloc ){
// System.out.println( "CompactSlices[" + SLICE_ENTRY_SIZES[i]+"] freeing " + current_alloc );
freed_one = true;
allocs[current_alloc] = false;
}
if ( freed_one ){
it = l.iterator();
while( it.hasNext()){
sliceBuffer sb = (sliceBuffer)it.next();
if ( !allocs[ sb.getAllocID()]){
it.remove();
}
}
}
}
}
}
}
protected int
getSliceIndex(
int _length )
{
for (int i=0;i<SLICE_ENTRY_SIZES.length;i++){
if ( _length <= SLICE_ENTRY_SIZES[i] ){
return( i );
}
}
Debug.out( "eh?");
return( 0 );
}
protected static class
sliceBuffer
{
private ByteBuffer buffer;
private short alloc_id;
private short slice_id;
protected
sliceBuffer(
ByteBuffer _buffer,
short _alloc_id,
short _slice_id )
{
buffer = _buffer;
alloc_id = _alloc_id;
slice_id = _slice_id;
}
protected ByteBuffer
getBuffer()
{
return( buffer );
}
protected short
getAllocID()
{
return( alloc_id );
}
protected short
getSliceID()
{
return( slice_id );
}
}
protected static class
sliceDBB
extends DirectByteBuffer
{
private sliceBuffer slice_buffer;
protected
sliceDBB(
byte _allocator,
sliceBuffer _sb )
{
super( _allocator, _sb.getBuffer(), pool );
slice_buffer = _sb;
}
protected sliceBuffer
getSliceBuffer()
{
return( slice_buffer );
}
}
protected static class
myInteger
{
int value;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -