/** * Copyright 2013, Landz and its contributors. All rights reserved. * * Licensed 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 z.offheap.contrast.netty; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.PooledByteBufAllocator; import org.junit.FixMethodOrder; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ErrorCollector; import org.junit.runners.MethodSorters; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class SlabFragmentationTest { private static final ByteBufAllocator POOLED_ALLOCATOR_DIRECT = new PooledByteBufAllocator(true); private static final int[] sizes = {0, 256, 1024, 4096, 65536, 256 * 1024, 1024 * 1024}; private static final ByteBufAllocator[] allocators = {POOLED_ALLOCATOR_DIRECT};// UNPOOLED_ALLOCATOR_DIRECT}; //XXX: ByteBuf instances should be on heap private ByteBuf[] bufs1; private ByteBuf[] bufs2; private ByteBuf[] bufs3; private ByteBuf[] bufs4; private ByteBuf[] bufs5; @Rule public ErrorCollector collector = new ErrorCollector(); @Test public void testSlabClassification1() { //============== sweep all bufs1 = new ByteBuf[100_000]; bufs2 = new ByteBuf[300_000]; bufs3 = new ByteBuf[150_000]; bufs4 = new ByteBuf[800_000]; bufs5 = new ByteBuf[5_000]; int size = 0; //============== < 800_000k initial free, but not sure exact number size = 7 * 1024; System.out.println("======1.1: apply 100_000*7k..."); for (int i = 0; i < 100_000; i++) { bufs1[i] = (POOLED_ALLOCATOR_DIRECT.buffer(size)); } // System.out.println(POOLED_ALLOCATOR_DIRECT); System.out.println("======1.2: free 50_000*7*1024..."); for (int i = 0; i < 50_000; i++) { bufs1[i].release(); } assertThat(bufs1[49_999].toString().contains("free"), is(true)); assertThat(bufs1[50_000].toString().contains("free"), is(false)); //============== 350_000k used size = 1024; System.out.println("======2.1: apply 300_000*1024(<50_000*7k)..."); for (int i = 0; i < 300_000; i++) { bufs2[i] = (POOLED_ALLOCATOR_DIRECT.buffer(size)); } System.out.println("======2.2: free all 1k bufs..."); for (int i = 0; i < bufs2.length; i++) { bufs2[i].release(); } assertThat(bufs2[0].toString().contains("free"), is(true)); assertThat(bufs2[1].toString().contains("free"), is(true)); //============== 350_000k used size = 2 * 1024; System.out.println("======3.1: apply 150_000*2k(=300_000*1024)..."); for (int i = 0; i < 150_000; i++) { bufs3[i] = (POOLED_ALLOCATOR_DIRECT.buffer(size)); } System.out.println("======3.2: free 100_000 2k bufs..."); for (int i = 0; i < 100_000; i++) { bufs3[i].release(); } assertThat(bufs3[99_999].toString().contains("free"), is(true)); assertThat(bufs3[100_000].toString().contains("free"), is(false)); //============== 450_000k used size = 256; System.out.println("======4.1: apply 800_000*256(=200_000*1024)..."); for (int i = 0; i < 800_000; i++) { bufs4[i] = (POOLED_ALLOCATOR_DIRECT.buffer(size)); } // System.out.println("======4.2: free all 800_000 256 bufs..."); // for (int i = 0; i < bufs4.length; i++) { // bufs4[i].release(); // } //============== 650_000k used size = 16 * 1024; System.out.println("======5.1: apply 5_000*16*1024(=80_000*1024)..."); for (int i = 0; i < 5_000; i++) { bufs5[i] = (POOLED_ALLOCATOR_DIRECT.buffer(size)); } //============== 730_000k used //============== free all for (ByteBuf buf : bufs1) if (buf != null && buf.refCnt() != 0) buf.release(); for (ByteBuf buf : bufs2) if (buf != null && buf.refCnt() != 0) buf.release(); for (ByteBuf buf : bufs3) if (buf != null && buf.refCnt() != 0) buf.release(); for (ByteBuf buf : bufs4) if (buf != null && buf.refCnt() != 0) buf.release(); for (ByteBuf buf : bufs5) if (buf != null && buf.refCnt() != 0) buf.release(); } @Test public void testSlabClassification2() { //============== sweep all bufs1 = new ByteBuf[100_000]; bufs2 = new ByteBuf[300_000]; bufs3 = new ByteBuf[150_000]; bufs4 = new ByteBuf[800_000]; bufs5 = new ByteBuf[2000]; int size = 0; //============== < 800_000k initial free, but not sure exact number size = 7 * 1024; System.out.println("======1.1: apply 100_000*7k..."); for (int i = 0; i < 100_000; i++) { bufs1[i] = (POOLED_ALLOCATOR_DIRECT.buffer(size)); } // System.out.println(POOLED_ALLOCATOR_DIRECT); System.out.println("======1.2: free 50_000*7*1024..."); for (int i = 0; i < 100_000; i += 2) { bufs1[i].release(); } assertThat(bufs1[49_999].toString().contains("free"), is(false)); assertThat(bufs1[50_000].toString().contains("free"), is(true)); //============== 350_000k used size = 1024; System.out.println("======2.1: apply 300_000*1024(<50_000*7k)..."); for (int i = 0; i < 300_000; i++) { bufs2[i] = (POOLED_ALLOCATOR_DIRECT.buffer(size)); } System.out.println("======2.2: free all 1k bufs..."); for (int i = 0; i < bufs2.length; i++) { bufs2[i].release(); } assertThat(bufs2[0].toString().contains("free"), is(true)); assertThat(bufs2[1].toString().contains("free"), is(true)); //============== 350_000k used size = 2 * 1024; System.out.println("======3.1: apply 150_000*2k(=300_000*1024)..."); for (int i = 0; i < 150_000; i++) { bufs3[i] = (POOLED_ALLOCATOR_DIRECT.buffer(size)); } System.out.println("======3.2: free 50_000 2k bufs from 0 to 50_000..."); for (int i = 0; i < 50_000; i++) { bufs3[i].release(); } System.out.println("======3.3: free 50_000 2k bufs from 50_000 to 150_000 in interleaved style..."); for (int i = 50_000; i < 150_000; i += 2) { bufs3[i].release(); } assertThat(bufs3[99_999].toString().contains("free"), is(false)); assertThat(bufs3[100_000].toString().contains("free"), is(true)); //============== 450_000k used size = 256; System.out.println("======4.1: apply 800_000*256(=200_000*1024)..."); for (int i = 0; i < 800_000; i++) { bufs4[i] = (POOLED_ALLOCATOR_DIRECT.buffer(size)); } //============== 650_000k used try { size = 16 * 1024; System.out.println("======5.1: apply 2000*16*1024(=32_000*1024)..."); for (int i = 0; i < 2000; i++) { bufs5[i] = (POOLED_ALLOCATOR_DIRECT.buffer(size)); } } catch (Exception e) { collector.addError(e); } finally { //============== free all System.out.println("======testSlabClassification2 free all..."); for (ByteBuf buf : bufs1) if (buf != null && buf.refCnt() != 0) buf.release(); for (ByteBuf buf : bufs2) if (buf != null && buf.refCnt() != 0) buf.release(); for (ByteBuf buf : bufs3) if (buf != null && buf.refCnt() != 0) buf.release(); for (ByteBuf buf : bufs4) if (buf != null && buf.refCnt() != 0) buf.release(); for (ByteBuf buf : bufs5) if (buf != null && buf.refCnt() != 0) buf.release(); System.out.println("======testSlabClassification2 done."); } //============== 682_000k used } @Test public void testSlabClassification3() { //============== sweep all bufs1 = new ByteBuf[500_000]; bufs2 = new ByteBuf[200_000]; bufs3 = null; bufs4 = null; bufs5 = null; try { int size = 0; //============== < 800_000k initial free, but not sure exact number size = 1024; System.out.println("======1.1: apply 500_000*1024..."); for (int i = 0; i < 500_000; i++) { bufs1[i] = (POOLED_ALLOCATOR_DIRECT.buffer(size)); } System.out.println("======1.2: free 250_000*1k bufs..."); for (int i = 0; i < 500_000; i += 2) { bufs1[i].release(); } assertThat(bufs1[250_000].toString().contains("free"), is(true)); assertThat(bufs1[249_999].toString().contains("free"), is(false)); //============== 250_000k used size = 256; System.out.println("======2.1: apply 200_000*256(=50_000*1024)..."); for (int i = 0; i < 200_000; i++) { bufs2[i] = (POOLED_ALLOCATOR_DIRECT.buffer(size)); } } catch (Exception e) { collector.addError(e); } finally { //============== free all System.out.println("======testSlabClassification3 free all..."); for (ByteBuf buf : bufs1) if (buf != null && buf.refCnt() != 0) buf.release(); for (ByteBuf buf : bufs2) if (buf != null && buf.refCnt() != 0) buf.release(); System.out.println("======testSlabClassification3 done."); } } }