Exemple #1
0
        /// <summary>
        /// Resize the heap encreasing the size by the specified value mantaining all data
        /// in the same position.
        /// </summary>
        /// <param name="size">Grow size in bytes (the actual grow size could be bigger than the specified).</param>
        /// <param name="noOvergrowth">Force the allocator to grow the heap by the exact specified size.</param>
        /// <returns>Returns <see cref="true"/> if the memory allocation has been done.</returns>
        public virtual bool Grow(uint size, bool noOvergrowth = false)
        {
            // - Check if the heap can grow
            if (!CanGrow)
            {
                return(false);
            }

            // - Check if we reached the memory limit
            if (HeapSize + size > MaximumSize)
            {
                return(false);
            }

            // - Calculates the actual grow size
            uint growSize = noOvergrowth ? size : (uint)(size + GrowFactor * HeapSize);

            try
            {
                // - Realloc the heap memory
                RawMemory = Marshal.ReAllocHGlobal(RawMemory, new IntPtr(HeapSize + growSize));
            }
            catch (OutOfMemoryException)
            {
                return(false);
            }

            // - Gets the last avaiable chunk of memory
            var lastChunk = FreeSpace.LastOrDefault();

            // - Create a new memory pointer pointing to the last block if there's no free block at the end
            if (lastChunk == null || lastChunk.Offset + lastChunk.Size < HeapSize)
            {
                FreeSpace.Add(new MemoryPointer(this, growSize, HeapSize));
            }

            // - Modify the existing chunk if it's at the end of the heap
            if (lastChunk != null || lastChunk.Offset + lastChunk.Size >= HeapSize)
            {
                lastChunk.ChangeOffsetAndSize(lastChunk.Offset, lastChunk.Size + growSize);
            }

            // - Update the heap size
            HeapSize += growSize;

            return(true);
        }
Exemple #2
0
        /// <summary>
        /// Shrinks the heap memory to the smallest memory that contains
        /// all the allocated blocks.
        /// </summary>
        /// <param name="keepBytes">Number of bytes to keep at the heap's tail.</param>
        /// <returns>Returns <see cref="true"/> if the shring goes well.</returns>
        public virtual bool FreeUnusedMemory(int keepBytes = -1)
        {
            // - Gets the last avaiable chunk of memory
            var lastChunk = FreeSpace.LastOrDefault();

            // - Create a new memory pointer pointing to the last block if there's no free block at the end
            if (lastChunk != null || lastChunk.Offset + lastChunk.Size >= HeapSize)
            {
                // - Automatically takes 10% of the whole size free if keepBytes is -1
                if (keepBytes < 0)
                {
                    keepBytes = (int)System.Math.Ceiling(HeapSize * 0.1);
                }

                // - Calculate the amount of memory to free
                uint shrinkSize = (uint)System.Math.Max(lastChunk.Size - keepBytes, 0);

                if (shrinkSize > 0)
                {
                    try
                    {
                        // - Realloc the heap memory
                        RawMemory = Marshal.ReAllocHGlobal(RawMemory, new IntPtr(HeapSize - shrinkSize));

                        // - Resize the last chunk
                        if (lastChunk.Size - shrinkSize > 0)
                        {
                            lastChunk.ChangeOffsetAndSize(lastChunk.Offset, lastChunk.Size - shrinkSize);
                        }
                        else
                        {
                            FreeSpace.Remove(lastChunk);
                        }

                        HeapSize -= shrinkSize;
                    }
                    catch (OutOfMemoryException)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }