this.stats.incFreeMemory(this.totalSlabSize); this.freeList = new FreeListManager();
private Chunk allocateFromFragments(int chunkSize, ChunkType chunkType) { do { final int lastAllocationId = this.lastFragmentAllocation.get(); for (int i=lastAllocationId; i < this.fragmentList.size(); i++) { Chunk result = allocateFromFragment(i, chunkSize, chunkType); if (result != null) { return result; } } for (int i=0; i < lastAllocationId; i++) { Chunk result = allocateFromFragment(i, chunkSize, chunkType); if (result != null) { return result; } } } while (compact(chunkSize)); // We tried all the fragments and didn't find any free memory. logOffHeapState(chunkSize); final OutOfOffHeapMemoryException failure = new OutOfOffHeapMemoryException("Out of off-heap memory. Could not allocate size of " + chunkSize); try { throw failure; } finally { SimpleMemoryAllocatorImpl.this.ooohml.outOfOffHeapMemory(failure); } }
private Chunk basicAllocate(int idx, int multiple, int offset, AtomicReferenceArray<SyncChunkStack> freeLists, boolean useFragments, ChunkType chunkType) { SyncChunkStack clq = freeLists.get(idx); if (clq != null) { long memAddr = clq.poll(); if (memAddr != 0) { Chunk result = SimpleMemoryAllocatorImpl.this.chunkFactory.newChunk(memAddr, chunkType); // Data integrity check. if(validateMemoryWithFill) { result.validateFill(SimpleMemoryAllocatorImpl.this.TINY_MULTIPLE); } result.readyForAllocation(chunkType); return result; } } if (useFragments) { return allocateFromFragments(((idx+1)*multiple)+offset, chunkType); } else { return null; } } private Chunk allocateHuge(int size, boolean useFragments, ChunkType chunkType) {
collectFreeChunks(freeChunks); final int SORT_ARRAY_BLOCK_SIZE = 128; long[] sorted = new long[SORT_ARRAY_BLOCK_SIZE]; fillFragments(); updateFragmentation();
assertEquals(TOTAL_MEM, ma.getFreeList().getFreeMemory()); MemoryChunk smc1 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null); MemoryChunk smc2 = ma.allocate(SMALL_ALLOC_SIZE-perObjectOverhead, null); smc2.release(); assertEquals(TOTAL_MEM-SMALL_ALLOC_SIZE, ma.getFreeList().getFreeMemory()); try { bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead, null); assertEquals(TOTAL_MEM, ma.getFreeList().getFreeMemory()); bmc = ma.allocate(BIG_ALLOC_SIZE-perObjectOverhead, null); bmc.release(); assertEquals(TOTAL_MEM, ma.getFreeList().getFreeMemory()); ArrayList<MemoryChunk> mcs = new ArrayList<MemoryChunk>(); for (int i=0; i < BIG_ALLOC_SIZE/(8+perObjectOverhead); i++) { assertEquals(0, ma.getFreeList().getFreeMemory()); try { ma.allocate(8, null); assertEquals(8+perObjectOverhead, ma.getFreeList().getFreeMemory()); mcs.remove(0).release(); // frees 8+perObjectOverhead assertEquals((8+perObjectOverhead)*2, ma.getFreeList().getFreeMemory()); ma.allocate(16, null).release(); // allocates and frees 16+perObjectOverhead; still have perObjectOverhead assertEquals((8+perObjectOverhead)*2, ma.getFreeList().getFreeMemory()); mcs.remove(0).release(); // frees 8+perObjectOverhead assertEquals((8+perObjectOverhead)*3, ma.getFreeList().getFreeMemory()); mcs.remove(0).release(); // frees 8+perObjectOverhead assertEquals((8+perObjectOverhead)*4, ma.getFreeList().getFreeMemory());
free(result.getMemoryAddress(), false); result = chunkFactory.newChunk(fragment.getMemoryAddress()+oldOffset, chunkSize, chunkType); allocSize -= chunkSize; Chunk result = basicAllocate(chunkSize, false, chunkType); if (result != null) { return result;
chunkType = GemFireChunk.TYPE; result = basicAllocate(size, true, chunkType); result.setDataSize(size);
return allocateFromFragments(round(TINY_MULTIPLE, size), chunkType); } else { return null;
@Override public StoredObject allocateAndInitialize(byte[] v, boolean isSerialized, boolean isCompressed, ChunkType chunkType) { long addr = OffHeapRegionEntryHelper.encodeDataAsAddress(v, isSerialized, isCompressed); if (addr != 0L) { return new DataAsAddress(addr); } if (chunkType == null) { chunkType = GemFireChunk.TYPE; } Chunk result = this.freeList.allocate(v.length, chunkType); //debugLog("allocated off heap object of size " + v.length + " @" + Long.toHexString(result.getMemoryAddress()), true); //debugLog("allocated off heap object of size " + v.length + " @" + Long.toHexString(result.getMemoryAddress()) + "chunkSize=" + result.getSize() + " isSerialized=" + isSerialized + " v=" + Arrays.toString(v), true); if (trackRefCounts) { refCountChanged(result.getMemoryAddress(), false, 1); } assert result.getChunkType() == chunkType: "chunkType=" + chunkType + " getChunkType()=" + result.getChunkType(); result.setSerializedValue(v); result.setSerialized(isSerialized); result.setCompressed(isCompressed); return result; }
private Chunk basicAllocate(int size, boolean useSlabs, ChunkType chunkType) { if (useSlabs) { // Every object stored off heap has a header so we need // to adjust the size so that the header gets allocated. // If useSlabs is false then the incoming size has already // been adjusted. size += Chunk.OFF_HEAP_HEADER_SIZE; } if (size <= MAX_TINY) { return allocateTiny(size, useSlabs, chunkType); // } else if (size <= MAX_BIG) { // return allocateBig(size, useSlabs); } else { return allocateHuge(size, useSlabs, chunkType); } }
@Override public long getFreeMemory() { return this.freeList.getFreeMemory(); }
private Chunk allocateTiny(int size, boolean useFragments, ChunkType chunkType) { return basicAllocate(getNearestTinyMultiple(size), TINY_MULTIPLE, 0, this.tinyFreeLists, useFragments, chunkType); } // private Chunk allocateBig(int size, boolean useFragments) {
private void freeTiny(long addr, int cSize) { basicFree(addr, getNearestTinyMultiple(cSize), this.tinyFreeLists); } // private void freeBig(long addr, int cSize) {
@Override public MemoryChunk allocate(int size, ChunkType chunkType) { //System.out.println("allocating " + size); Chunk result = this.freeList.allocate(size, chunkType); //("allocated off heap object of size " + size + " @" + Long.toHexString(result.getMemoryAddress()), true); if (trackRefCounts) { refCountChanged(result.getMemoryAddress(), false, 1); } return result; }