2017-02-01 4 views
0

Это кажется глупой ошибкой, поскольку я не мог найти, почему все записи не были удалены. Я бегу с JAVA_OPTS:Netty PooledDirect ByteBuf и ArrayList неожиданное поведение

-XX: MaxDirectMemorySize = 67108864 -Dio.netty.leakDetectionLevel = расширенный D-Dio.netty.allocator.type = складочный -XX: + UseG1GC -Xms40m -Xmx40m -Dio. netty.allocator.numDirectArenas = 4

Вот полный код:

private ByteBufAllocator alloc = PooledByteBufAllocator.DEFAULT; 

//Configure the arena 
//java -Dio.netty.allocator.numDirectArenas=... -Dio.netty.allocator.numHeapArenas=... 
public ByteBuf createObject(int size){ 
    return alloc.directBuffer(size); 
} 

public static void main(String[] args) throws InterruptedException { 
    ArrayList<ByteBuf> arr = new ArrayList<>(); 
    try { 
     DiameterLoggingConfiguration.initLogger(); 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    ByufferTest bt = new ByufferTest(); 
    //Total of 66060288 ~ slightly less than 64 mb of direct memory 
    for(int i=0;i<64512;i++){ 
     //Each instance of 1024 bytes 
     arr.add(bt.createObject(1024)); 

    } 

    BufferedReader br = new BufferedReader(new 
       InputStreamReader(System.in)); 
    try { 
     br.readLine(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    System.out.println("Now releasing.."+arr.size()); 

    for(int i=0;i<arr.size();i++){ 
     ByteBuf b = arr.remove(i); 
     b.release(); 
    } 

    System.out.println("Now array size ="+arr.size()); 

    Thread.sleep(100000); 

} 

Выход:

сейчас освобождение..64512 После того, как размер массива = 32256

Не знаю, что только половина элементов была удалена. Все еще есть записи ByteBuf в ArrayList.

ответ

1

Это потому, что вы используете:

for(int i=0;i<arr.size();i++){ 
    ByteBuf b = arr.remove(i); 
    b.release(); 
} 

Это будет не работать, как вы увеличиваете индекс на 0, но и удалить буфер. Таким образом вы будете пропускать буферы.

Лучше использовать Queue и просто использовать poll();

Queue<ByteBuf> arr = new ArrayDeque<>(); 
for(;;){ 
    ByteBuf b = arr.poll(); 
    if (b == null) { 
     break; 
    } 
    b.release(); 
} 
+0

Это действительно работает.Thanx много @Norman – GauravTheGeek