Live data from Hacker News

.NET GC Internals mini-series

tooslowexception.com

31–40 of 77 posts

Re: .NET GC Internals mini-series

#31
post #21

Anyone have a good comparison of .net vs java GCs? I never had trouble with the former but Java has been terrible. I'm not sure if its just my project or having the xmx memory cap.

I am quite interested in this also and I confirm it from empirical standpoint - I never had a single episode of .NET GC but it was usual stuff on Java apps. We even had 3 month session in GC optimization directly with the guy working at Sun on it.

Re: .NET GC Internals mini-series

#32
post #2

How do I know this person really knows about .NET GC internals for me to spend any time watching some videos?

Just read the source code. It has everything you'll ever need:

https://raw.githubusercontent.com/dotnet/runtime/master/src/...

Or spend an hour listening to this person. Who knows his videos might have some bits of important information.

Re: .NET GC Internals mini-series

#33
post #24

Please forgive me ignorance, but why can't I manually delete an object? Lots of times I know this one object is pretty big and want to delete it when I am done with it, but have to force the GC to run to clean it up.

Because they're memory objects that are managed by .Net. If you said "Hey, I'm done with this" that's great, but .Net can't actually delete it until it's checked for itself that nothing else is using it. Otherwise you'll inject an error into the memory manager when you delete an object that's still in use. So you can kinda fake a delete by releasing the last reference to an object and then forcing a garbage collectio…

But gc.collect is quite expensive. I think the parent question was, I have a large object in memory, I want to delete it now so that I can load another large object without running into memory limits. But I don't want to call gc.collect which will stop my whole application, interfer with the garbage collector heuristics, and do all sort of unecessay steps.

I had instances where I knew only one of these large structures could fit in memory and had to call gc.collect before allocating a new one, as I would get an outofmemory exception before the garbage collector would kick in by itself.

You can do that with unmanaged objects but it doesn't look like you can with managed objects (other than gc.collect which I saw on other videos is not recommended by microsoft).

Re: .NET GC Internals mini-series

#34
post #26
post #24

Please forgive me ignorance, but why can't I manually delete an object? Lots of times I know this one object is pretty big and want to delete it when I am done with it, but have to force the GC to run to clean it up.

With a GC like the one used in .NET, «deleting» an object is a noop. It wouldn’t give you any benefits over not deleting it. You only pay a price for living things (as in, some object holding a reference to it), the rest is free.

No I had instances where I deleted an object, wanted to allocate a new one, only one of these would fit in memory, and got an outofmemory exception because the GC didn't kick in between the two. So it is not equivalent.

Re: .NET GC Internals mini-series

#36
post #24

Please forgive me ignorance, but why can't I manually delete an object? Lots of times I know this one object is pretty big and want to delete it when I am done with it, but have to force the GC to run to clean it up.

Allocate it via Marshal.AllocHGlobal, and use unsafe to place it there.

Then you can allocate and deallocate at will.

Or just use a struct.

Re: .NET GC Internals mini-series

#37
post #34
post #26

Earlier quoted context omitted.

With a GC like the one used in .NET, «deleting» an object is a noop. It wouldn’t give you any benefits over not deleting it. You only pay a price for living things (as in, some object holding a reference to it), the rest is free.

No I had instances where I deleted an object, wanted to allocate a new one, only one of these would fit in memory, and got an outofmemory exception because the GC didn't kick in between the two. So it is not equivalent.

The GC kicks in when allocating a new object and it decides it needs more memory. GC likely kicked in as you allocated the last object, and after the collection phase, still didn’t have enough memory and so failed.

I believe objects with destructors can keep an object alive for an extra collection phase, but I believe if that’s the case it can easily be solved with a using block before allocating the next object.

Re: .NET GC Internals mini-series

#38
post #20
post #14

Maybe for some readers: Likely GC abbreviates garbage collection . Going way back, some programming languages have permitted dynamic storage allocation , that is, a programmer using that language could during execution of the program ask for storage , that is, bytes in main memory, to be allocated , i.e., made available for use. Later the programming could free that storage. E.g., early versions of the programming la…

> E.g., early versions of the programming language Fortran did not offer dynamic storage allocation, but some programmers would implement their own, say, in a Fortran array. Then for pointers to the allocated storage, just use a subscript on the array name. Even today people do the same thing in languages like Java and Rust as workarounds for performance or semantic constraints of the environment while still nominall…

Because at least array indices are bounds checked.

Pointers require hardware support for the same purpose, which Oracle, ARM, Microsoft, Apple and Google are putting money into to, as means to fix C and C++.

Re: .NET GC Internals mini-series

#39
post #37
post #34

Earlier quoted context omitted.

No I had instances where I deleted an object, wanted to allocate a new one, only one of these would fit in memory, and got an outofmemory exception because the GC didn't kick in between the two. So it is not equivalent.

The GC kicks in when allocating a new object and it decides it needs more memory. GC likely kicked in as you allocated the last object, and after the collection phase, still didn’t have enough memory and so failed. I believe objects with destructors can keep an object alive for an extra collection phase, but I believe if that’s the case it can easily be solved with a using block before allocating the next object.

No that wasn't the problem. You should be able to test it yourself for instance by opening and dereferencing a lot of system.drawing images but not disposing them. You will most likely get an out of memory exception (unless the behavior changed in the last couple of years, and I have not tested it on .net core). Unfortunately the GC doesn't immediatly kick in when you have a memory pressure and you will get an out of memory exception even though there is a lot of garbage ready to be collected (and in my case it was managed objects, not images).

Re: .NET GC Internals mini-series

#40
post #33

Earlier quoted context omitted.

Because they're memory objects that are managed by .Net. If you said "Hey, I'm done with this" that's great, but .Net can't actually delete it until it's checked for itself that nothing else is using it. Otherwise you'll inject an error into the memory manager when you delete an object that's still in use. So you can kinda fake a delete by releasing the last reference to an object and then forcing a garbage collectio…

But gc.collect is quite expensive. I think the parent question was, I have a large object in memory, I want to delete it now so that I can load another large object without running into memory limits. But I don't want to call gc.collect which will stop my whole application, interfer with the garbage collector heuristics, and do all sort of unecessay steps. I had instances where I knew only one of these large structur…

[deleted]
Post reply on HN