forked from KNEMC/KLALB
KLALB3.2
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
package org.kne.cloud.network;
|
||||
|
||||
import java.lang.ref.Cleaner;
|
||||
import java.lang.ref.PhantomReference;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.kne.debug.TimeDebugger;
|
||||
public class ByteBufferAllocator {
|
||||
private List<ByteBufferPool> bbfps=new ArrayList<>();
|
||||
|
||||
private ByteBufferPool[]bbfpsarr;
|
||||
|
||||
|
||||
private ReferenceQueue<ByteBuffer> refq=new ReferenceQueue<>();
|
||||
private boolean isDirect;
|
||||
|
||||
public ByteBufferAllocator(boolean isDirect) {
|
||||
this.isDirect=isDirect;
|
||||
int i=1;
|
||||
int maxi=0;
|
||||
int mps=16;
|
||||
for (int j = 0; j < 18; j++) {
|
||||
int count=100;
|
||||
mps+=count;
|
||||
bbfps.add(new ByteBufferPool(mps, i,isDirect));
|
||||
maxi=i;
|
||||
i<<=1;
|
||||
}
|
||||
bbfpsarr=new ByteBufferPool[maxi];
|
||||
for (int j = 0; j < bbfpsarr.length; j++) {
|
||||
bbfpsarr[j]=getByteBufferPool(j);
|
||||
}
|
||||
|
||||
Thread t= new Thread(()->{
|
||||
while(true) {
|
||||
try {
|
||||
Reference<? extends ByteBuffer> ref;
|
||||
ref = refq.remove();
|
||||
if(ref!=null) {
|
||||
ref.clear();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// TODO 自动生成的 catch 块
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
t.setPriority(Thread.MAX_PRIORITY-1);
|
||||
t.start();
|
||||
}
|
||||
public ByteBuffer allocate(int capacity) {
|
||||
if(true) {
|
||||
return allocateHeap(capacity);
|
||||
}
|
||||
//new Exception().printStackTrace();
|
||||
ByteBufferPool bbfp=bbfpsarr[capacity];
|
||||
ByteBuffer bbf=null;
|
||||
try {
|
||||
bbf=bbfp.borrow();
|
||||
}catch(OutOfMemoryError err) {
|
||||
System.gc();
|
||||
Thread.yield();
|
||||
bbf=bbfp.borrow();
|
||||
}
|
||||
ByteBuffer bbfs=bbf.slice(0, capacity);
|
||||
|
||||
new ByteBufferPhantomReference(bbfs,refq,bbf,bbfp);
|
||||
return bbfs;
|
||||
}
|
||||
private static ByteBuffer allocateHeap(int capacity) {
|
||||
return ByteBuffer.wrap(new byte[capacity]);
|
||||
}
|
||||
private ByteBufferPool getByteBufferPool(int capacity) {
|
||||
int elen=0;
|
||||
for (int i = 0; i < bbfps.size(); i++) {
|
||||
ByteBufferPool bfp=bbfps.get(i);
|
||||
if(capacity<=(elen= bfp.getLength())) {
|
||||
return bfp;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("capacity:"+capacity+">"+elen);
|
||||
}
|
||||
private static class ByteBufferPhantomReference extends PhantomReference<ByteBuffer>{
|
||||
|
||||
private static AtomicReference<ByteBufferPhantomReference> first=new AtomicReference<>(null);
|
||||
|
||||
private AtomicReference<ByteBufferPhantomReference> next=new AtomicReference<>(null);
|
||||
private AtomicReference<ByteBufferPhantomReference> prev=new AtomicReference<>(null);
|
||||
|
||||
private ByteBuffer father;
|
||||
private ByteBufferPool pool;
|
||||
|
||||
public ByteBufferPhantomReference(ByteBuffer referent, ReferenceQueue<? super ByteBuffer> q,ByteBuffer father,ByteBufferPool pool) {
|
||||
super(referent, q);
|
||||
this.father=father;
|
||||
this.pool=pool;
|
||||
insert();
|
||||
}
|
||||
|
||||
private void insert() {
|
||||
ByteBufferPhantomReference refn= first.getAndSet(this);
|
||||
if(refn!=null) {
|
||||
next.set(refn);
|
||||
refn.prev.set(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void remove() {
|
||||
ByteBufferPhantomReference prevn= prev.getAndSet(null);
|
||||
ByteBufferPhantomReference nextn=next.getAndSet(null);
|
||||
if(prevn!=null)
|
||||
prevn.next.set(nextn);
|
||||
if(nextn!=null)
|
||||
nextn.prev.set(prevn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
//System.out.println("clear");
|
||||
pool.back(father);
|
||||
remove();
|
||||
super.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user