示例#1
0
        public override void Free(OffHeapBlockAllocator_MemoryBlock block, MemoryAllocationTracker tracker)
        {
            if (_released || !IsCacheable(block.Size))
            {
                DoFree(block, tracker);
                return;
            }

//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final java.util.concurrent.BlockingQueue<OffHeapBlockAllocator_MemoryBlock> cache = caches[log2floor(block.size)];
            BlockingQueue <OffHeapBlockAllocator_MemoryBlock> cache = _caches[log2floor(block.Size)];

            if (!cache.offer(block))
            {
                DoFree(block, tracker);
                return;
            }

            // it is possible that allocator is released just before we put the block into queue;
            // in such case case we need to free memory right away, since release() will never be called again
            if (_released && cache.remove(block))
            {
                DoFree(block, tracker);
                return;
            }

            tracker.Deallocated(block.UnalignedSize);
        }
示例#2
0
        public override OffHeapBlockAllocator_MemoryBlock Allocate(long size, MemoryAllocationTracker tracker)
        {
            while (true)
            {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final long usedMemoryBefore = usedMemory.get();
                long usedMemoryBefore = _usedMemory.get();
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final long usedMemoryAfter = usedMemoryBefore + size;
                long usedMemoryAfter = usedMemoryBefore + size;
                if (usedMemoryAfter > _maxMemory)
                {
                    throw new Exception(format("Can't allocate %d bytes due to exceeding memory limit; used=%d, max=%d", size, usedMemoryBefore, _maxMemory));
                }
                if (_usedMemory.compareAndSet(usedMemoryBefore, usedMemoryAfter))
                {
                    break;
                }
            }
            try
            {
                return(_impl.allocate(size, tracker));
            }
            catch (Exception t)
            {
                _usedMemory.addAndGet(-size);
                throw t;
            }
        }
示例#3
0
        public MuninnPageCache(PageSwapperFactory swapperFactory, MemoryAllocator memoryAllocator, int cachePageSize, PageCacheTracer pageCacheTracer, PageCursorTracerSupplier pageCursorTracerSupplier, VersionContextSupplier versionContextSupplier, JobScheduler jobScheduler)
        {
            VerifyHacks();
            VerifyCachePageSizeIsPowerOfTwo(cachePageSize);
            int maxPages = CalculatePageCount(memoryAllocator, cachePageSize);

            // Expose the total number of pages
            pageCacheTracer.MaxPages(maxPages);
            MemoryAllocationTracker memoryTracker = GlobalMemoryTracker.INSTANCE;

            this._pageCacheId              = _pageCacheIdCounter.incrementAndGet();
            this._swapperFactory           = swapperFactory;
            this._cachePageSize            = cachePageSize;
            this._keepFree                 = Math.Min(_pagesToKeepFree, maxPages / 2);
            this._pageCacheTracer          = pageCacheTracer;
            this._pageCursorTracerSupplier = pageCursorTracerSupplier;
            this._versionContextSupplier   = versionContextSupplier;
            this._printExceptionsOnClose   = true;
            long alignment = swapperFactory.RequiredBufferAlignment;

            this.VictimPage = VictimPageReference.GetVictimPage(cachePageSize, memoryTracker);
            this.Pages      = new PageList(maxPages, cachePageSize, memoryAllocator, new SwapperSet(), VictimPage, alignment);
            this._scheduler = jobScheduler;

            FreelistHead = new AtomicInteger();
        }
示例#4
0
 internal Grab(Grab next, long size, MemoryAllocationTracker memoryTracker)
 {
     this.NextConflict  = next;
     this.Address       = UnsafeUtil.allocateMemory(size, memoryTracker);
     this.Limit         = Address + size;
     this.MemoryTracker = memoryTracker;
     NextPointer        = Address;
 }
示例#5
0
 internal Grab(Grab next, long address, long limit, long nextPointer, MemoryAllocationTracker memoryTracker)
 {
     this.NextConflict  = next;
     this.Address       = address;
     this.Limit         = limit;
     this.NextPointer   = nextPointer;
     this.MemoryTracker = memoryTracker;
 }
示例#6
0
        /// <summary>
        /// Allocate a block of memory of the given size in bytes and update memory allocation tracker accordingly.
        /// <para>
        /// The memory is aligned such that it can be used for any data type.
        /// The memory is uninitialised, so it may contain random garbage, or it may not.
        /// </para>
        /// </summary>
        /// <returns> a pointer to the allocated memory </returns>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public static long allocateMemory(long bytes, org.neo4j.memory.MemoryAllocationTracker allocationTracker) throws NativeMemoryAllocationRefusedError
        public static long AllocateMemory(long bytes, MemoryAllocationTracker allocationTracker)
        {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final long pointer = allocateMemory(bytes);
            long pointer = AllocateMemory(bytes);

            allocationTracker.Allocated(bytes);
            return(pointer);
        }
示例#7
0
 public override void Free(OffHeapBlockAllocator_MemoryBlock block, MemoryAllocationTracker tracker)
 {
     try
     {
         _impl.free(block, tracker);
     }
     finally
     {
         _usedMemory.addAndGet(-block.Size);
     }
 }
示例#8
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @VisibleForTesting MemoryBlock allocateNew(long size, org.neo4j.memory.MemoryAllocationTracker tracker)
        internal virtual MemoryBlock AllocateNew(long size, MemoryAllocationTracker tracker)
        {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final long unalignedSize = requirePositive(size) + Long.BYTES - 1;
            long unalignedSize = requirePositive(size) + Long.BYTES - 1;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final long unalignedAddr = org.neo4j.unsafe.impl.internal.dragons.UnsafeUtil.allocateMemory(unalignedSize, tracker);
            long unalignedAddr = UnsafeUtil.allocateMemory(unalignedSize, tracker);
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final long addr = org.neo4j.unsafe.impl.internal.dragons.UnsafeUtil.alignedMemory(unalignedAddr, Long.BYTES);
            long addr = UnsafeUtil.alignedMemory(unalignedAddr, Long.BYTES);

            return(new OffHeapBlockAllocator_MemoryBlock(addr, size, unalignedAddr, unalignedSize));
        }
示例#9
0
 /// <summary>
 /// Create a new GrabAllocator that will allocate the given amount of memory, to pointers that are aligned to the
 /// given alignment size. </summary>
 /// <param name="expectedMaxMemory"> The maximum amount of memory that this memory manager is expected to allocate. The
 /// actual amount of memory used can end up greater than this value, if some of it gets wasted on alignment padding. </param>
 /// <param name="memoryTracker"> memory usage tracker </param>
 internal GrabAllocator(long expectedMaxMemory, MemoryAllocationTracker memoryTracker)
 {
     this._grabs = new Grabs(expectedMaxMemory, memoryTracker);
     try
     {
         CleanerHandles handles = FindCleanerHandles();
         this._cleaner     = handles.Creator.invoke(this, new GrabsDeallocator(_grabs));
         this._cleanHandle = handles.Cleaner;
     }
     catch (Exception throwable)
     {
         throw new LinkageError("Unable to instantiate cleaner", throwable);
     }
 }
示例#10
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test void maxMemoryLimit()
        internal virtual void MaxMemoryLimit()
        {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final org.neo4j.memory.MemoryAllocationTracker tracker = mock(org.neo4j.memory.MemoryAllocationTracker.class);
            MemoryAllocationTracker tracker = mock(typeof(MemoryAllocationTracker));
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final OffHeapBlockAllocator allocator = mock(OffHeapBlockAllocator.class);
            OffHeapBlockAllocator allocator = mock(typeof(OffHeapBlockAllocator));

            when(allocator.Allocate(anyLong(), any(typeof(MemoryAllocationTracker)))).then(invocation =>
            {
                long size = invocation.getArgument <long>(0);
                return(new MemoryBlock(0, size, 0, size));
            });
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final CapacityLimitingBlockAllocatorDecorator decorator = new CapacityLimitingBlockAllocatorDecorator(allocator, 1024);
            CapacityLimitingBlockAllocatorDecorator decorator = new CapacityLimitingBlockAllocatorDecorator(allocator, 1024);

//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final java.util.List<org.neo4j.kernel.impl.util.collection.OffHeapBlockAllocator_MemoryBlock> blocks = new java.util.ArrayList<>();
            IList <OffHeapBlockAllocator_MemoryBlock> blocks = new List <OffHeapBlockAllocator_MemoryBlock>();

            for (int i = 0; i < 8; i++)
            {
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final org.neo4j.kernel.impl.util.collection.OffHeapBlockAllocator_MemoryBlock block = decorator.allocate(128, tracker);
                OffHeapBlockAllocator_MemoryBlock block = decorator.Allocate(128, tracker);
                blocks.Add(block);
            }

            assertThrows(typeof(Exception), () => decorator.Allocate(128, tracker));

            decorator.Free(blocks.RemoveAt(0), tracker);
            assertDoesNotThrow(() => decorator.Allocate(128, tracker));

            assertThrows(typeof(Exception), () => decorator.Allocate(256, tracker));
            decorator.Free(blocks.RemoveAt(0), tracker);
            assertThrows(typeof(Exception), () => decorator.Allocate(256, tracker));

            decorator.Free(blocks.RemoveAt(0), tracker);
            assertDoesNotThrow(() => decorator.Allocate(256, tracker));
        }
示例#11
0
        protected internal UnsafeTable(int capacity, int bytesPerKey, VALUE valueMarker, MemoryAllocationTracker allocationTracker) : base(capacity, 32)
        {
            UnsafeUtil.assertHasUnsafe();
            this.AllocationTracker = allocationTracker;
            this._bytesPerKey      = bytesPerKey;
            this._bytesPerEntry    = 4 + bytesPerKey;
            this.ValueMarker       = valueMarker;
            this._dataSize         = ( long )this.CapacityConflict * _bytesPerEntry;

            // Below is a piece of code which ensures that allocated memory is aligned to 4-byte boundary
            // if memory system requires aligned memory access. The reason we pick 4-byte boundary is that
            // it's the lowest common denominator and the size of our hop-bits field for every entry.
            // So even for a table which would only deal with, say longs (8-byte), it would still need to
            // read and write 4-byte hop-bits fields. Therefore this table can, if required to, read anything
            // bigger than 4-byte fields as multiple 4-byte fields. This way it can play well with aligned
            // memory access requirements.

            Debug.Assert(_bytesPerEntry % Integer.BYTES == 0, "Bytes per entry needs to be divisible by 4, this constraint " +);
            "is checked because on memory systems requiring aligned memory access this would otherwise break.";

            if (UnsafeUtil.allowUnalignedMemoryAccess)
            {
                _allocatedBytes        = _dataSize;
                this._allocatedAddress = this._address = UnsafeUtil.allocateMemory(_allocatedBytes, this.AllocationTracker);
            }
            else
            {
                // There's an assertion above also verifying this, but it's only an actual problem if our memory system
                // requires aligned access, which seems to be the case right here and now.
                if ((_bytesPerEntry % Integer.BYTES) != 0)
                {
                    throw new System.ArgumentException("Memory system requires aligned memory access and " + this.GetType().Name + " was designed to cope with this requirement by " + "being able to accessing data in 4-byte chunks, if needed to. " + "Although this table tried to be constructed with bytesPerKey:" + bytesPerKey + " yielding a bytesPerEntry:" + _bytesPerEntry + ", which isn't 4-byte aligned.");
                }

                _allocatedBytes        = _dataSize + Integer.BYTES - 1;
                this._allocatedAddress = UnsafeUtil.allocateMemory(_allocatedBytes, this.AllocationTracker);
                this._address          = UnsafeUtil.alignedMemory(_allocatedAddress, Integer.BYTES);
            }

            ClearMemory();
        }
示例#12
0
        public override OffHeapBlockAllocator_MemoryBlock Allocate(long size, MemoryAllocationTracker tracker)
        {
            requirePositive(size);
            checkState(!_released, "Allocator is already released");
            if (!IsCacheable(size))
            {
                return(AllocateNew(size, tracker));
            }

//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final java.util.concurrent.BlockingQueue<OffHeapBlockAllocator_MemoryBlock> cache = caches[log2floor(size)];
            BlockingQueue <OffHeapBlockAllocator_MemoryBlock> cache = _caches[log2floor(size)];
            OffHeapBlockAllocator_MemoryBlock block = cache.poll();

            if (block == null)
            {
                block = AllocateNew(size, tracker);
            }
            else
            {
                tracker.Allocated(block.UnalignedSize);
            }
            return(block);
        }
 public ThreadSafePeakMemoryAllocationTracker(MemoryAllocationTracker alsoReportTo)
 {
     this._alsoReportTo = alsoReportTo;
 }
示例#14
0
 public OffHeapMemoryAllocator(MemoryAllocationTracker tracker, OffHeapBlockAllocator blockAllocator)
 {
     this._tracker        = requireNonNull(tracker);
     this._blockAllocator = requireNonNull(blockAllocator);
 }
示例#15
0
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @VisibleForTesting void doFree(OffHeapBlockAllocator_MemoryBlock block, org.neo4j.memory.MemoryAllocationTracker tracker)
        internal virtual void DoFree(OffHeapBlockAllocator_MemoryBlock block, MemoryAllocationTracker tracker)
        {
            UnsafeUtil.free(block.UnalignedAddr, block.UnalignedSize, tracker);
        }
示例#16
0
 internal Grabs(long expectedMaxMemory, MemoryAllocationTracker memoryTracker)
 {
     this.ExpectedMaxMemory = expectedMaxMemory;
     this.MemoryTracker     = memoryTracker;
 }
示例#17
0
 /// <summary>
 /// Free the memory that was allocated with <seealso cref="allocateMemory"/> and update memory allocation tracker accordingly.
 /// </summary>
 public static void Free(long pointer, long bytes, MemoryAllocationTracker allocationTracker)
 {
     Free(pointer, bytes);
     allocationTracker.Deallocated(bytes);
 }
示例#18
0
 public UnsafeDirectByteBufferAllocator(MemoryAllocationTracker memoryAllocationTracker)
 {
     this._memoryAllocationTracker = memoryAllocationTracker;
 }