GSF.IO.Unmanaged.MemoryPoolPageList.GrowMemoryPool C# (CSharp) Method

GrowMemoryPool() public method

Grows the buffer pool to have the desired size
public GrowMemoryPool ( long size ) : bool
size long
return bool
        public bool GrowMemoryPool(long size)
        {
            long sizeBefore;
            long sizeAfter;
            lock (m_syncRoot)
            {
                if (m_disposed)
                    throw new ObjectDisposedException(GetType().FullName);

                sizeBefore = CurrentCapacity;

                size = Math.Min(size, MaximumPoolSize);
                while (CurrentCapacity < size)
                {
                    Memory memory = new Memory(m_memoryBlockSize);
                    int pageIndex = m_memoryBlocks.ReplaceFirstNullOrAdd(memory);
                    m_memoryBlockAllocations++;
                    m_isPageFree.EnsureCapacity((pageIndex + 1) * m_pagesPerMemoryBlock);
                    m_isPageFree.SetBits(pageIndex * m_pagesPerMemoryBlock, m_pagesPerMemoryBlock);
                }

                sizeAfter = CurrentCapacity;

            }

            return sizeBefore != sizeAfter;
        }

Usage Example

Example #1
0
        /// <summary>
        /// Determines whether to allocate more memory or to do a collection cycle on the existing pool.
        /// </summary>
        private void RequestMoreFreeBlocks()
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("Collection Cycle Started");
            bool lockTaken;

            Monitor.Enter(m_syncRoot); lockTaken = true;
            try
            {
                long size               = CurrentCapacity;
                int  collectionLevel    = GetCollectionLevelBasedOnSize(size);
                long stopShrinkingLimit = CalculateStopShrinkingLimit(size);

                RemoveDeadEvents();

                sb.Append("Level: " + GetCollectionLevelString(collectionLevel));
                sb.AppendFormat(" Desired Size: {0}/{1}MB", stopShrinkingLimit >> 20, CurrentCapacity >> 20);
                sb.AppendLine();

                for (int x = 0; x < collectionLevel; x++)
                {
                    if (CurrentAllocatedSize < stopShrinkingLimit)
                    {
                        break;
                    }
                    CollectionEventArgs eventArgs = new CollectionEventArgs(ReleasePage, MemoryPoolCollectionMode.Normal, 0);

                    Monitor.Exit(m_syncRoot); lockTaken = false;

                    foreach (WeakEventHandler <CollectionEventArgs> c in m_requestCollectionEvent)
                    {
                        c.TryInvoke(this, eventArgs);
                    }

                    Monitor.Enter(m_syncRoot); lockTaken = true;

                    sb.AppendFormat("Pass {0} Usage: {1}/{2}MB", x + 1, CurrentAllocatedSize >> 20, CurrentCapacity >> 20);
                    sb.AppendLine();
                }

                long currentSize = CurrentAllocatedSize;
                long sizeBefore  = CurrentCapacity;
                if (m_pageList.GrowMemoryPool(currentSize + (long)(0.1 * MaximumPoolSize)))
                {
                    long sizeAfter = CurrentCapacity;
                    m_releasePageVersion++;

                    sb.AppendFormat("Grew buffer pool {0}MB -> {1}MB", sizeBefore >> 20, sizeAfter >> 20);
                    sb.AppendLine();
                }

                if (m_pageList.FreeSpaceBytes < 0.05 * MaximumPoolSize)
                {
                    int pagesToBeReleased = (int)((0.05 * MaximumPoolSize - m_pageList.FreeSpaceBytes) / PageSize);

                    sb.AppendFormat("* Emergency Collection Occuring. Attempting to release {0} pages.", pagesToBeReleased);
                    sb.AppendLine();

                    Log.Publish(MessageLevel.Warning, MessageFlags.PerformanceIssue, "Pool Emergency", string.Format("Memory pool is reaching an Emergency level. Desiring Pages To Release: {0}", pagesToBeReleased));

                    CollectionEventArgs eventArgs = new CollectionEventArgs(ReleasePage, MemoryPoolCollectionMode.Emergency, pagesToBeReleased);

                    Monitor.Exit(m_syncRoot); lockTaken = false;

                    foreach (WeakEventHandler <CollectionEventArgs> c in m_requestCollectionEvent)
                    {
                        if (eventArgs.DesiredPageReleaseCount == 0)
                        {
                            break;
                        }
                        c.TryInvoke(this, eventArgs);
                    }

                    Monitor.Enter(m_syncRoot); lockTaken = true;

                    if (eventArgs.DesiredPageReleaseCount > 0)
                    {
                        sb.AppendFormat("** Critical Collection Occuring. Attempting to release {0} pages.", pagesToBeReleased);
                        sb.AppendLine();

                        Log.Publish(MessageLevel.Warning, MessageFlags.PerformanceIssue, "Pool Critical", string.Format("Memory pool is reaching an Critical level. Desiring Pages To Release: {0}", eventArgs.DesiredPageReleaseCount));

                        eventArgs = new CollectionEventArgs(ReleasePage, MemoryPoolCollectionMode.Critical, eventArgs.DesiredPageReleaseCount);

                        Monitor.Exit(m_syncRoot); lockTaken = false;

                        foreach (WeakEventHandler <CollectionEventArgs> c in m_requestCollectionEvent)
                        {
                            if (eventArgs.DesiredPageReleaseCount == 0)
                            {
                                break;
                            }
                            c.TryInvoke(this, eventArgs);
                        }

                        Monitor.Enter(m_syncRoot); lockTaken = true;
                    }
                }

                sw.Stop();
                sb.AppendFormat("Elapsed Time: {0}ms", sw.Elapsed.TotalMilliseconds.ToString("0.0"));
                Log.Publish(MessageLevel.Info, "Memory Pool Collection Occured", sb.ToString());

                RemoveDeadEvents();
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(m_syncRoot);
                }
            }
        }