private static void OnMemoryCollected(object sender, MemoryCollectedEventArgs args) { Delegate[] delegates; lock (_syncLock) { if (args.IsLast) { _collecting = false; } if (_memoryCollected != null) { delegates = _memoryCollected.GetInvocationList(); } else { delegates = new Delegate[0]; } } foreach (Delegate @delegate in delegates) { try { @delegate.DynamicInvoke(_strategy, args); } catch (Exception e) { Platform.Log(LogLevel.Warn, e, "Unexpected error encountered during memory collection notification."); } } }
/// <summary> /// Fires the <see cref="MemoryCollected"/> event. /// </summary> protected void OnMemoryCollected(MemoryCollectedEventArgs args) { try { EventsHelper.Fire(_memoryCollected, this, args); } catch (Exception e) { Platform.Log(LogLevel.Warn, e, "Unexpected failure while firing memory collected event."); } }
private void OnMemoryCollected(object sender, MemoryCollectedEventArgs args) { if (args.IsLast) { lock (_waitObject) { Platform.Log(LogLevel.Debug, "'Last' memory collection signal detected; releasing waiting thread."); Monitor.Pulse(_waitObject); } lock (_syncLock) { --_waitingClients; } } }
private void OnMemoryCollected(object sender, MemoryCollectedEventArgs args) { lock (_waitObject) { Platform.Log(LogLevel.Debug, "Received memory collected signal; waiting to see if more memory is required."); Monitor.Pulse(_waitObject); if (_needMoreMemory) { Monitor.Wait(_waitObject); args.NeedMoreMemory = _needMoreMemory; } if (!_needMoreMemory) { lock (_syncLock) { --_waitingClients; MemoryCollected -= OnMemoryCollected; } } } }
public override void Collect(MemoryCollectionArgs collectionArgs) { _largeObjectEnumerator = collectionArgs.LargeObjectContainers.GetEnumerator(); _regenerationCost = RegenerationCost.Low; //TODO (Time Review): Use Environment.TickCount? _collectionStartTime = DateTime.Now; _timeSinceLastCollection = _collectionStartTime - _lastCollectionTime; TimeSpan thirtySeconds = TimeSpan.FromSeconds(30); if (_timeSinceLastCollection < thirtySeconds) { Platform.Log(LogLevel.Debug, "Time since last collection is less than 30 seconds; adjusting to 30 seconds."); _timeSinceLastCollection = thirtySeconds; } _maxTimeSinceLastAccess = _timeSinceLastCollection; _maxTimeSinceLastAccessDecrement = TimeSpan.FromSeconds(_timeSinceLastCollection.TotalSeconds / 3); _totalNumberOfCollections = 0; _totalBytesCollected = 0; _totalLargeObjectsCollected = 0; _totalContainersUnloaded = 0; try { CodeClock clock = new CodeClock(); clock.Start(); Collect(); clock.Stop(); PerformanceReportBroker.PublishReport("Memory", "Collect", clock.Seconds); } catch (Exception e) { Platform.Log(LogLevel.Warn, e, "Default memory management strategy failed to collect."); } finally { DateTime collectionEndTime = DateTime.Now; if (_totalContainersUnloaded > 0) { _lastCollectionTime = collectionEndTime; } _largeObjectEnumerator = null; TimeSpan totalElapsed = collectionEndTime - _collectionStartTime; MemoryCollectedEventArgs finalArgs = new MemoryCollectedEventArgs( _totalContainersUnloaded, _totalLargeObjectsCollected, _totalBytesCollected, totalElapsed, true); if (_totalNumberOfCollections != 0 || _totalBytesCollected != 0 || _totalLargeObjectsCollected != 0 || _totalContainersUnloaded != 0) { Platform.Log(LogLevel.Info, "Large object collection summary: freed {0} MB in {1} seconds and {2} iterations, Total Containers: {3}, Total Large Objects: {4}", _totalBytesCollected / (float)OneMegabyte, totalElapsed.TotalSeconds, _totalNumberOfCollections, _totalContainersUnloaded, _totalLargeObjectsCollected); } OnMemoryCollected(finalArgs); } }
private void Collect(long bytesToCollect) { bool continueCollecting = false; bool needMoreMemorySignalled = false; if (bytesToCollect <= 0) { Platform.Log(LogLevel.Debug, "Memory is not above high watermark; firing collected event to check if more memory is required."); MemoryCollectedEventArgs args = new MemoryCollectedEventArgs(0, 0, 0, TimeSpan.Zero, false); OnMemoryCollected(args); continueCollecting = needMoreMemorySignalled = args.NeedMoreMemory; } else { continueCollecting = true; Platform.Log(LogLevel.Debug, "Memory *is* above high watermark; collecting ..."); } if (!continueCollecting) { return; } int batchSize = 10; int collectionNumber = 0; while (continueCollecting) { CodeClock clock = new CodeClock(); clock.Start(); long bytesCollected = 0; int largeObjectsCollected = 0; int containersUnloaded = 0; int i = 0; foreach (ILargeObjectContainer container in GetNextBatchOfContainersToCollect(batchSize)) { ++i; try { long bytesHeldBefore = container.BytesHeldCount; int largeObjectsHeldBefore = container.LargeObjectCount; container.Unload(); long bytesHeldAfter = container.BytesHeldCount; int largeObjectsHeldAfter = container.LargeObjectCount; int largeObjectsHeldDifference = largeObjectsHeldBefore - largeObjectsHeldAfter; largeObjectsCollected += largeObjectsHeldDifference; if (largeObjectsHeldDifference > 0) { ++containersUnloaded; } long bytesDifference = (bytesHeldBefore - bytesHeldAfter); bytesCollected += bytesDifference; _totalBytesCollected += bytesDifference; } catch (Exception e) { Platform.Log(LogLevel.Warn, e, "An unexpected error occurred while attempting to collect large object memory."); } //when needMoreMemorySignalled is true, we need to be more aggressive and keep collecting. if (!needMoreMemorySignalled && _totalBytesCollected >= bytesToCollect) { break; } } batchSize *= 2; _totalContainersUnloaded += containersUnloaded; _totalLargeObjectsCollected += largeObjectsCollected; ++_totalNumberOfCollections; clock.Stop(); continueCollecting = i > 0; if (!continueCollecting) { continue; } PerformanceReportBroker.PublishReport("Memory", "CollectionIteration", clock.Seconds); MemoryCollectedEventArgs args = new MemoryCollectedEventArgs( containersUnloaded, largeObjectsCollected, bytesCollected, TimeSpan.FromSeconds(clock.Seconds), false); OnMemoryCollected(args); needMoreMemorySignalled = args.NeedMoreMemory; continueCollecting = needMoreMemorySignalled || _totalBytesCollected < bytesToCollect; if (Platform.IsLogLevelEnabled(LogLevel.Debug)) { Platform.Log(LogLevel.Debug, "Large object collection #{0}: freed {1} MB in {2}, Containers Unloaded: {3}, Large Objects Collected: {4}, Need More Memory: {5}, Last Batch: {6}", ++collectionNumber, args.BytesCollectedCount / (float)OneMegabyte, clock, containersUnloaded, largeObjectsCollected, needMoreMemorySignalled, i); } } CollectGarbage(); }
/// <summary> /// Fires the <see cref="MemoryCollected"/> event. /// </summary> protected void OnMemoryCollected(MemoryCollectedEventArgs args) { try { EventsHelper.Fire(_memoryCollected, this, args); } catch(Exception e) { Platform.Log(LogLevel.Warn, e, "Unexpected failure while firing memory collected event."); } }
public override void Collect(MemoryCollectionArgs collectionArgs) { _largeObjectEnumerator = collectionArgs.LargeObjectContainers.GetEnumerator(); _regenerationCost = RegenerationCost.Low; //TODO (Time Review): Use Environment.TickCount? _collectionStartTime = DateTime.Now; _timeSinceLastCollection = _collectionStartTime - _lastCollectionTime; TimeSpan thirtySeconds = TimeSpan.FromSeconds(30); if (_timeSinceLastCollection < thirtySeconds) { Platform.Log(LogLevel.Debug, "Time since last collection is less than 30 seconds; adjusting to 30 seconds."); _timeSinceLastCollection = thirtySeconds; } _maxTimeSinceLastAccess = _timeSinceLastCollection; _maxTimeSinceLastAccessDecrement = TimeSpan.FromSeconds(_timeSinceLastCollection.TotalSeconds / 3); _totalNumberOfCollections = 0; _totalBytesCollected = 0; _totalLargeObjectsCollected = 0; _totalContainersUnloaded = 0; try { CodeClock clock = new CodeClock(); clock.Start(); Collect(); clock.Stop(); PerformanceReportBroker.PublishReport("Memory", "Collect", clock.Seconds); } catch (Exception e) { Platform.Log(LogLevel.Warn, e, "Default memory management strategy failed to collect."); } finally { DateTime collectionEndTime = DateTime.Now; if (_totalContainersUnloaded > 0) _lastCollectionTime = collectionEndTime; _largeObjectEnumerator = null; TimeSpan totalElapsed = collectionEndTime - _collectionStartTime; MemoryCollectedEventArgs finalArgs = new MemoryCollectedEventArgs( _totalContainersUnloaded, _totalLargeObjectsCollected, _totalBytesCollected, totalElapsed, true); if ( _totalNumberOfCollections != 0 || _totalBytesCollected != 0 || _totalLargeObjectsCollected != 0 ||_totalContainersUnloaded != 0) Platform.Log(LogLevel.Info, "Large object collection summary: freed {0} MB in {1} seconds and {2} iterations, Total Containers: {3}, Total Large Objects: {4}", _totalBytesCollected/(float)OneMegabyte, totalElapsed.TotalSeconds, _totalNumberOfCollections, _totalContainersUnloaded, _totalLargeObjectsCollected); OnMemoryCollected(finalArgs); } }
private void Collect(long bytesToCollect) { bool continueCollecting = false; bool needMoreMemorySignalled = false; if (bytesToCollect <= 0) { Platform.Log(LogLevel.Debug, "Memory is not above high watermark; firing collected event to check if more memory is required."); MemoryCollectedEventArgs args = new MemoryCollectedEventArgs(0, 0, 0, TimeSpan.Zero, false); OnMemoryCollected(args); continueCollecting = needMoreMemorySignalled = args.NeedMoreMemory; } else { continueCollecting = true; Platform.Log(LogLevel.Debug, "Memory *is* above high watermark; collecting ..."); } if (!continueCollecting) return; int batchSize = 10; int collectionNumber = 0; while (continueCollecting) { CodeClock clock = new CodeClock(); clock.Start(); long bytesCollected = 0; int largeObjectsCollected = 0; int containersUnloaded = 0; int i = 0; foreach (ILargeObjectContainer container in GetNextBatchOfContainersToCollect(batchSize)) { ++i; try { long bytesHeldBefore = container.BytesHeldCount; int largeObjectsHeldBefore = container.LargeObjectCount; container.Unload(); long bytesHeldAfter = container.BytesHeldCount; int largeObjectsHeldAfter = container.LargeObjectCount; int largeObjectsHeldDifference = largeObjectsHeldBefore - largeObjectsHeldAfter; largeObjectsCollected += largeObjectsHeldDifference; if (largeObjectsHeldDifference > 0) ++containersUnloaded; long bytesDifference = (bytesHeldBefore - bytesHeldAfter); bytesCollected += bytesDifference; _totalBytesCollected += bytesDifference; } catch (Exception e) { Platform.Log(LogLevel.Warn, e, "An unexpected error occurred while attempting to collect large object memory."); } //when needMoreMemorySignalled is true, we need to be more aggressive and keep collecting. if (!needMoreMemorySignalled && _totalBytesCollected >= bytesToCollect) break; } batchSize *= 2; _totalContainersUnloaded += containersUnloaded; _totalLargeObjectsCollected += largeObjectsCollected; ++_totalNumberOfCollections; clock.Stop(); continueCollecting = i > 0; if (!continueCollecting) continue; PerformanceReportBroker.PublishReport("Memory", "CollectionIteration", clock.Seconds); MemoryCollectedEventArgs args = new MemoryCollectedEventArgs( containersUnloaded, largeObjectsCollected, bytesCollected, TimeSpan.FromSeconds(clock.Seconds), false); OnMemoryCollected(args); needMoreMemorySignalled = args.NeedMoreMemory; continueCollecting = needMoreMemorySignalled || _totalBytesCollected < bytesToCollect; if (Platform.IsLogLevelEnabled(LogLevel.Debug)) { Platform.Log(LogLevel.Debug, "Large object collection #{0}: freed {1} MB in {2}, Containers Unloaded: {3}, Large Objects Collected: {4}, Need More Memory: {5}, Last Batch: {6}", ++collectionNumber, args.BytesCollectedCount / (float)OneMegabyte, clock, containersUnloaded, largeObjectsCollected, needMoreMemorySignalled, i); } } CollectGarbage(); }