Sunteți pe pagina 1din 41

http://netponto.

org

80ª Reunião Presencial @ LISBOA


DateTimeOffset.Parse(“25-05-2019”, new CultureInfo(“pt-PT”));

hashtag #netponto
Patrocinadores “GOLD”

Twitter: @PremiumMinds https://www.premium-minds.com


Patrocinadores “Silver”
Patrocinadores “Bronze”
Garbage Collection
The do’s and don’ts !!
Me
• Pedro Rosa
• p@mainhub.pt
• 961624203
• https://www.mainhub.pt
• https://www.makers.pt
Agenda
• Reference Types vs Value Types
• Fundamentals of Garbage Collection
• Fundamentals of Memory
• Generations
• Small and Large Object Heap
• Server vs Workstation Garbage Collection
• Concurrent vs Non-concurrent
• Weak References
• IDisposable Patern
Reference Types vs Value Types
• Heap vs Stack?
• Value types go to the stack?
• If a value type is part of a class (as in your
example), it will end up on the heap.
• If it's boxed, it will end up on the heap.
• If it's in an array, it will end up on the
heap.
• If it's a static variable, it will end up on the
heap.
• If it's captured by a closure, it will end up
on the heap.
• If it's used in an iterator or async block, it
will end up on the heap.
• If it's created by unsafe or unmanaged
code, it could be allocated in any type of
data structure (not necessarily a stack or a
heap).

https://www.c-sharpcorner.com/article/C-Sharp-heaping-vs-stacking-in-net-part-i/
https://blogs.msdn.microsoft.com/ericlippert/2010/09/30/the-truth-about-value-types/
DEMO
Boxing vs Unboxing
Fundamentals of Garbage Collection
• .NET's garbage collector manages the allocation and
release of memory for your application.
• Each time you create a new object, the common
language runtime allocates memory for the object from
the managed heap. As long as address space is available
in the managed heap, the runtime continues to allocate
space for new objects.
• However, memory is not infinite. Eventually the garbage
collector must perform a collection in order to free some
memory.
• The garbage collector's optimizing engine determines the
best time to perform a collection, based upon the
allocations being made.
• When the garbage collector performs a collection, it
checks for objects in the managed heap that are no
longer being used by the application and performs the
necessary operations to reclaim their memory.
Fundamentals of Memory
The following list summarizes important CLR memory concepts.
• Each process has its own, separate virtual address space. All processes on the
same computer share the same physical memory.
• By default, on 32-bit computers, each process has a 2-GB user-mode virtual
address space.
• Virtual address space can get fragmented. This means that there are free
blocks, also known as holes, in the address space. When a virtual memory
allocation is requested, the virtual memory manager has to find a single free
block that is large enough to satisfy that allocation request. Even if you have 2
GB of free space, the allocation that requires 2 GB will be unsuccessful unless all
of that free space is in a single address block.
• You can run out of memory if you run out of virtual address space to reserve
or physical space to commit.
Conditions for a Garbage Collection
• Garbage collection occurs when one of
the following conditions is true:
• The system has low physical memory. This is
detected by either the low memory
notification from the OS or low memory
indicated by the host.
• The memory that is used by allocated objects
on the managed heap surpasses an
acceptable threshold. This threshold is
continuously adjusted as the process runs.
• The GC.Collect method is called. In almost all
cases, you do not have to call this method,
because the garbage collector runs
continuously. This method is primarily used
for unique situations and testing.
DEMO
GC
Generations
• New, small, objects go into
generation 0.
• When a collection occurs, any
objects that are no longer in use (no
references to them) have their
memory freed up (deallocated).
• Any objects still in use
will survive and promoted to the next
generation.
The Small Object Heap
• Small .NET objects are allocated onto the Small Object Heaps (SOH). There are
three of these: Generation 0, Generation 1, and Generation 2. Objects move up
these Generations based on their age.
• New objects are placed on Gen 0. When Gen 0 becomes full, the .NET
Garbage Collector (GC) runs, disposing of objects which are no longer needed
and moving everything else up to Gen 1. If Gen 1 becomes full the GC runs
again, but also moves objects in Gen 1 up to Gen 2.
• A full GC run happens when Gen 2 becomes full. This clears unneeded Gen 2
objects, moves Gen 1 objects to Gen 2, then moves Gen 0 objects to Gen 1,
and finally clears anything which isn't referenced. After each GC run, the
affected heaps are compacted, to keep memory which is still in use together.
• This generational approach keeps things running efficiently – the time-
consuming compacting process only occurs when absolutely necessary.
The Large Object Heap
• Objects larger than 85 KB are allocated onto the Large Object Heap (LOH).
They aren't compacted, because of the overhead of copying large chunks of
memory. When a full GC takes place, the address ranges of LOH objects not in
use are recorded in a free space allocation table instead.
• When a new object is allocated, this free space table is checked for an address
range large enough to hold the object. If one exists, the object is allocated
there, if not, it's allocated at the next free space.
• Because objects are unlikely to be the exact size of an empty address range,
small chunks of memory will almost always be left between objects, resulting in
fragmentation. If these chunks are less than 85 KB, there's no possibility of
reuse at all. Consequently, as allocation demand increases, new segments are
reserved even though fragmented space is still available.
• Furthermore, when a large object needs to be allocated, .NET tends to append
the object to the end anyway, rather than run an expensive Gen 2 GC. This is
good for performance but a significant cause of memory fragmentation
DEMO
LOH vs SMO vs Generations vs GC
What Happens During a Garbage Collection
A garbage collection has the following phases:
• A marking phase that finds and creates a list of all live
objects.
• A relocating phase that updates the references to the
objects that will be compacted.
• A compacting phase that reclaims the space occupied
by the dead objects and compacts the surviving
objects. The compacting phase moves objects that
have survived a garbage collection toward the older
end of the segment.
• Because generation 2 collections can occupy multiple
segments, objects that are promoted into generation 2
can be moved into an older segment. Both generation
1 and generation 2 survivors can be moved to a
different segment, because they are promoted to
generation 2.
Garbage Collector Different Running Modes
The GC can run in different modes depending on type of application:
• Workstation Mode
• Server Mode
• Concurrent mode
• Non Concurrent mode

https://blogs.msdn.microsoft.com/seteplia/2017/01/05/understanding-different-gc-modes-with-concurrency-visualizer/
Garbage Collector Different Running Modes
Workstation mode gives maximum responsiveness to the user and
cuts down pauses due to GC.
• The collection occurs on the user thread that triggered the garbage
collection and remains at the same priority. Because user threads
typically run at normal priority, the garbage collector (which runs on
a normal priority thread) must compete with other threads for CPU
time.
• It can run as 'concurrent' or 'non-concurrent', referring to the
thread the GC runs on.
• Default is concurrent, which uses a separate thread for the GC so
the application can continue execution while GC runs.
https://blogs.msdn.microsoft.com/seteplia/2017/01/05/understanding-different-gc-modes-with-concurrency-visualizer/
Garbage Collector Different Running Modes
Server mode gives maximum throughput, scalability, and performance for server
environments.
• The collection occurs on multiple dedicated threads that are running at
THREAD_PRIORITY_HIGHEST priority level.
• Because multiple garbage collection threads work together, server garbage collection
is faster than workstation garbage collection on the same size heap.
• Segment sizes and generation thresholds are typically much larger in Server mode
than Workstation mode, reflecting the higher demands placed on servers.
• Server mode runs garbage collection in parallel on multiple threads, allocating a
separate SOH and LOH to each logical processor to prevent the threads from
interfering with each other.
• The .NET framework provides a cross-referencing mechanism so objects can still
reference each other across the heaps. However, as application responsiveness isn't a
direct goal of Server mode, all application threads are suspended for the duration of
the GC.
https://blogs.msdn.microsoft.com/seteplia/2017/01/05/understanding-different-gc-modes-with-concurrency-visualizer/
Garbage Collector Different Running Modes
• Workstation vs Server
Garbage Collector Different Running Modes
• Non-concurrent vs Concurrent vs Background
Garbage Collector Different Running Modes
• By default every console application uses
Background Workstation .
• This table clearly shows the huge difference
between Server GC and Workstation GC for this
application: just by switching from default
Workstation GC to Server GC End-to-End time
dropped by 30%! There are two reasons for this:
number of managed heaps and segment size.
• Bigger segments allow allocating more objects in
ephemeral segment and drastically reduces number
of Gen0 and Gen1 collections: from 3500 to 200.
• Lower number of garbage collections significantly
reduced the total allocations size (from 170Gb to
17Gb).
• Another interesting data point is the number of
GC pauses that took longer than 200ms and
mean GC duration for different workstation GC
flavors.
https://devblogs.microsoft.com/dotnet/author/maoni/
Garbage Collector Methods & Properties
• GC.Collect()
• Forces an immediate garbage collection of all
generations.
• GC.GetGeneration
• Returns the current generation number of an object.
• GC.SuppressFinalize(Object)
• Requests that the common language runtime not call
the finalizer for the specified object.
• GCCollectionMode (enum)
• Specifies the behavior for a forced garbage collection.
• GC.MaxGeneration
• Gets the maximum number of generations that the
system currently supports.
When to call GC.Collect()
Rule #1 - Don't.
• This is really the most important rule. It's
fair to say that most usages of
GC.Collect() are a bad idea
• Rule #2
• Consider calling GC.Collect() if some non-
recurring event has just happened and
this event is highly likely to have caused a
lot of old objects to die.
DEMO
Garbage Collector Methods &
Properties
Weak References
• A weak reference permits the garbage collector to
collect the object while still allowing the
application to access the object.
• A weak reference is valid only during the
indeterminate amount of time until the object is
collected when no strong references exist. When
you use a weak reference, the application can still
obtain a strong reference to the object, which
prevents it from being collected. However, there is
always the risk that the garbage collector will get
to the object first before a strong reference is
reestablished.
• Weak references are useful for objects that use a
lot of memory, but can be recreated easily if they
are reclaimed by garbage collection.
Weak References
WeakReference.IsAlive
• Gets an indication whether the object referenced
by the current WeakReference object has been
garbage collected.
WeakReference.Target
• Gets or sets the object (the target) referenced by
the current WeakReference object.
WeakReference.TrackResurrection
• Gets an indication whether the object referenced
by the current WeakReference object is tracked
after it is finalized.
DEMO
Weak References
Very Strong References 
Making a class that never dies!!!
IDisposable and the Dispose Pattern
The pattern for disposing an object, referred to as a dispose pattern,
imposes order on the lifetime of an object.
• The dispose pattern is used only for objects that access unmanaged
resources, such as file and pipe handles, registry handles, wait
handles, or pointers to blocks of unmanaged memory.
• This is because the garbage collector is very efficient at reclaiming
unused managed objects, but it is unable to reclaim unmanaged
objects.
IDisposable and the Dispose Pattern
Used when our classes make use of
unmanaged resources.. and only then.

http://www.informit.com/articles/article.aspx?p=2756468&seqNum=7
IDisposable and the Dispose
Pattern
• The darkened objects are no more referenced and should be
collected.
• B, G and H do not implement finalizers so that could be discarded.
• E, I and J are not going to be discarded as their classes implement
a finalizer.
• Finalization list was holding a “weak” reference to them since they were
created.
• These references are moved to the FReacheable queue and the collection
ends.
• Later on, after the collection ends, the finalizer thread wakes up and calls
the finalizer of all objects referenced by the FReacheable queue.
• This is the important part of the issue:
• It means that even though those objects weren’t referenced anymore, they
couldn’t be collected nor their memory be reclaimed because the finalizer thread
has not run yet.
• As they could not be reclaimed, they are promoted to the next generation just like
other survivors.
• So if those objects were in generation 0, they now end up in generation 1,
extending their lifetime. It’s even worse if they get promoted from generation 1 to
generation 2, as the next gen 2 collection might happen only very far in the future.
• This artificially increases the memory consumption of the application.
Using statement
Provides a convenient syntax that
ensures the correct use
of IDisposable objects.
Garbage Collector Methods & Properties
• GC.SuppressFinalize(Object)
• Requests that the common language runtime not call the finalizer for the
specified object.
• GC.WaitForPendingFinalizers
• Suspends the current thread until the thread that is processing the queue of
finalizers has emptied that queue.
DEMO
IDisposable and the Dispose
Pattern
Why SafeHandle?
• Before the .NET Framework version 2.0, all operating system handles could only be
encapsulated in the IntPtr managed wrapper object. While this was a convenient way
to interoperate with native code, handles could be leaked by asynchronous
exceptions, such as a thread aborting unexpectedly or a stack overflow. These
asynchronous exceptions are an obstacle to cleaning up operating system resources,
and they can occur almost anywhere in your app.
• Although overrides to the Object.Finalize method allow cleanup of unmanaged
resources when an object is being garbage collected, in some circumstances,
finalizable objects can be reclaimed by garbage collection while executing a method
within a platform invoke call.
• If a finalizer frees the handle passed to that platform invoke call, it could lead to
handle corruption. The handle could also be reclaimed while your method is blocked
during a platform invoke call, such as while reading a file.
• More critically, because Windows aggressively recycles handles, a handle could be
recycled and point to another resource that might contain sensitive data. This is known
as a recycle attack and can potentially corrupt data and be a security threat.
Questions?
Pedro Rosa

p@mainhub.pt
http://bit.ly/netponto-aval-80

* Para quem não puder preencher durante a reunião,


iremos enviar um email com o link à tarde

S-ar putea să vă placă și