public virtual void Dispose() { if (_disposed) { return; } Reset(); _objectJsonParser.Dispose(); _documentBuilder.Dispose(); _arenaAllocator.Dispose(); _arenaAllocatorForLongLivedValues?.Dispose(); if (_managedBuffers != null) { foreach (var managedPinnedBuffer in _managedBuffers) { managedPinnedBuffer.Dispose(); } _managedBuffers = null; } if (_pinnedObjects != null) { foreach (var pinnedObject in _pinnedObjects) { pinnedObject.Free(); } } _disposed = true; }
public JsonOperationContext(int initialSize, int longLivedSize, SharedMultipleUseFlag lowMemoryFlag) { Debug.Assert(lowMemoryFlag != null); _disposeOnceRunner = new DisposeOnce <ExceptionRetry>(() => { #if MEM_GUARD_STACK ElectricFencedMemory.DecrementConext(); ElectricFencedMemory.UnRegisterContextAllocation(this); #endif Reset(true); _documentBuilder.Dispose(); _arenaAllocator.Dispose(); _arenaAllocatorForLongLivedValues?.Dispose(); if (_managedBuffers != null) { foreach (var managedPinnedBuffer in _managedBuffers) { managedPinnedBuffer.Dispose(); } _managedBuffers = null; } if (_pinnedObjects != null) { foreach (var pinnedObject in _pinnedObjects) { pinnedObject.Free(); } _pinnedObjects = null; } }); _initialSize = initialSize; _longLivedSize = longLivedSize; _arenaAllocator = new ArenaMemoryAllocator(lowMemoryFlag, initialSize); _arenaAllocatorForLongLivedValues = new ArenaMemoryAllocator(lowMemoryFlag, longLivedSize); CachedProperties = new CachedProperties(this); _jsonParserState = new JsonParserState(); _objectJsonParser = new ObjectJsonParser(_jsonParserState, this); _documentBuilder = new BlittableJsonDocumentBuilder(this, _jsonParserState, _objectJsonParser); LowMemoryFlag = lowMemoryFlag; #if MEM_GUARD_STACK ElectricFencedMemory.IncrementConext(); ElectricFencedMemory.RegisterContextAllocation(this, Environment.StackTrace); #endif }
public override void Dispose() { if (_disposed) { return; } lock (this) { if (_disposed) { return; } #if MEM_GUARD_STACK ElectricFencedMemory.DecrementConext(); ElectricFencedMemory.UnRegisterContextAllocation(this); #endif Reset(true); _documentBuilder.Dispose(); _arenaAllocator.Dispose(); _arenaAllocatorForLongLivedValues?.Dispose(); if (_managedBuffers != null) { foreach (var managedPinnedBuffer in _managedBuffers) { managedPinnedBuffer.Dispose(); } _managedBuffers = null; } if (_pinnedObjects != null) { foreach (var pinnedObject in _pinnedObjects) { pinnedObject.Free(); } } _disposed = true; } }
protected internal virtual unsafe void Reset() { if (_tempBuffer != null) { _arenaAllocator.Return(_tempBuffer); _tempBuffer.Address = null; } foreach (var builder in _liveReaders) { builder.DisposeTrackingReference = null; builder.Dispose(); } _liveReaders.Clear(); _arenaAllocator.ResetArena(); _documentBuilder.Reset(); if (_tempBuffer != null) { GetNativeTempBuffer(_tempBuffer.SizeInBytes); } // We don't reset _arenaAllocatorForLongLivedValues. It's used as a cache buffer for long lived strings like field names. // When a context is re-used, the buffer containing those field names was not reset and the strings are still valid and alive. if (_arenaAllocatorForLongLivedValues.Allocated > _initialSize) { // at this point, the long lived section is far too large, this is something that can happen // if we have dynamic properties. A back of the envelope calculation gives us roughly 32K // property names before this kicks in, which is a true abuse of the system. In this case, // in order to avoid unlimited growth, we'll reset the long lived section _arenaAllocatorForLongLivedValues.Dispose(); _arenaAllocatorForLongLivedValues = null; _fieldNames.Clear(); CachedProperties = null; // need to release this so can be collected } }