public DefaultResourceLeak(ResourceLeakDetector owner, object referent) { this.owner = owner; GCNotice existingNotice; if (owner.gcNotificationMap.TryGetValue(referent, out existingNotice)) { existingNotice.Rearm(this); } else { owner.gcNotificationMap.Add(referent, new GCNotice(this)); } if (referent != null) { DetectionLevel level = Level; if (level >= DetectionLevel.Advanced) { this.creationRecord = NewRecord(null); } else { this.creationRecord = null; } Interlocked.Increment(ref this.owner.active); } else { this.creationRecord = null; this.freed = 1; } }
/// <summary> /// Creates a new <see cref="IResourceLeak" /> which is expected to be closed via <see cref="IResourceLeak.Close()" /> /// when the /// related resource is deallocated. /// </summary> /// <returns>the <see cref="IResourceLeak" /> or <c>null</c></returns> public IResourceLeak Open(object obj) { DetectionLevel level = Level; switch (level) { case DetectionLevel.Disabled: return(null); case DetectionLevel.Paranoid: this.CheckForCountLeak(level); return(new DefaultResourceLeak(this, obj)); case DetectionLevel.Simple: case DetectionLevel.Advanced: if (this.leakCheckCnt++ % this.samplingInterval == 0) { this.CheckForCountLeak(level); return(new DefaultResourceLeak(this, obj)); } else { return(null); } default: throw new ArgumentOutOfRangeException(); } }
/// <summary> /// Creates a new <see cref="IResourceLeakTracker" /> which is expected to be closed /// when the /// related resource is deallocated. /// </summary> /// <returns>the <see cref="IResourceLeakTracker" /> or <c>null</c></returns> public IResourceLeakTracker Track(object obj) { DetectionLevel level = Level; if (level == DetectionLevel.Disabled) { return(null); } if (level < DetectionLevel.Paranoid) { if (0u >= (uint)(PlatformDependent.GetThreadLocalRandom().Next(this.samplingInterval))) { return(new DefaultResourceLeak(this, obj)); } else { return(null); } } else { return(new DefaultResourceLeak(this, obj)); } }
public DefaultResourceLeak(ResourceLeakDetector owner, object referent) { this.owner = owner; owner.gcNotificationMap.Add(referent, new GCNotice(this)); if (referent != null) { DetectionLevel level = Level; if (level >= DetectionLevel.Advanced) { this.creationRecord = NewRecord(null, 3); } else { this.creationRecord = null; } Interlocked.Increment(ref this.owner.active); } else { this.creationRecord = null; this.freed = 1; } }
public DefaultResourceLeak(ResourceLeakDetector owner, object referent) { Debug.Assert(referent != null); this.owner = owner; if (owner.gcNotificationMap.TryGetValue(referent, out GCNotice existingNotice)) { existingNotice.Rearm(this); } else { owner.gcNotificationMap.Add(referent, new GCNotice(this, referent)); } DetectionLevel level = Level; if (level >= DetectionLevel.Advanced) { this.creationRecord = NewRecord(null); } else { this.creationRecord = null; } }
internal void CheckForCountLeak(DetectionLevel level) { // Report too many instances. int interval = level == DetectionLevel.Paranoid ? 1 : this.samplingInterval; if (Volatile.Read(ref this.active) * interval > this.maxActive && Interlocked.CompareExchange(ref this.loggedTooManyActive, 0, 1) == 0) { Logger.Error("LEAK: You are creating too many " + this.resourceType + " instances. " + this.resourceType + " is a shared resource that must be reused across the AppDomain," + "so that only a few instances are created."); } }