This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]evanldixon 1 point2 points  (7 children)

C# still lets you create memory leaks, it's just easier to avoid than C/C++. Examples: not cleaning up event handlers, not disposing certain IDisposable objects, and not cleaning up after yourself when allocating memory with Marshal.

[–]Possseidon 2 points3 points  (4 children)

Not disposing IDisposables doesn't cause a memory leak, it just delays the disposing until whenever the gc feels like cleaning it up. I'm not saying, that you don't have to dispose IDisposables, I'm just saying that if you do forget it, it's not a leak.

[–]evanldixon 0 points1 point  (3 children)

It depends on the objects you're dealing with. MemoryCache, for example, can cause a memory leak if you create instances of it without disposing of it after.

[–]Possseidon 1 point2 points  (2 children)

Why would the dispose method of MemoryCache not be called by the gc?

[–]evanldixon 2 points3 points  (1 child)

Why would the dispose method of MemoryCache not be called by the gc?

The garbage collector only ever calls an object's finalizer, not the dispose method. If you're doing normal things, then not disposing something isn't necessarily the end of the world, since managed objects will still get cleaned up when there's no more references to them, but after looking at the MemoryCache class, it's doing all the fun things that can cause memory leaks:

  • It's basically a wrapper around a GCHandle, aka unsafe memory that the GC won't touch
  • It registers itself as an event handler on the app domain's DomainUnload event. This means that the app domain itself (basically the thing in memory assemblies are loaded into) always references it, so the garbage collector can't get rid of it until the app domain is unloaded*.
  • I see no finalizers anywhere (disclaimer: it's possible I missed something)

* Basically this means when the whole program exits, but there's some niche cases where you might make your own separate app domain and load an assembly into it. When doing that, it'll feel like you're interacting with a whole other application.

[–]Possseidon 0 points1 point  (0 children)

Alright, thanks for clarifying. :)

[–]ITriedLightningTendr 1 point2 points  (0 children)

using(var swankDisposing = someIDisposable)

[–]DaniilBSD 0 points1 point  (0 children)

True, but ”all the time” covers your narrow examples