Add heuristic to trigger GC to finalize dead threads and clean up han… (dotnet/corecl...
authorKoundinya Veluri <kouvel@microsoft.com>
Mon, 27 Mar 2017 18:10:07 +0000 (11:10 -0700)
committerGitHub <noreply@github.com>
Mon, 27 Mar 2017 18:10:07 +0000 (11:10 -0700)
commiteb84def758d32fb7ee44f488b29911a186985cf0
tree42fff720d6b6f00800de1770a5f06d2cf32c2edd
parent805c22ef0af01a3724ef635f51fa423dd8c44c7b
Add heuristic to trigger GC to finalize dead threads and clean up han… (dotnet/coreclr#10413)

Add heuristic to trigger GC to finalize dead threads and clean up handles and memory

A thread that is started allocates some handles in Thread::AllocHandles(). After it terminates, the managed thread object needs to be collected by a GC for the handles to be released. Some applications that are mostly idle but have a timer ticking periodically will cause a thread pool thread to be created on each tick, since the thread pool preserves threads for a maximum of 20 seconds currently. Over time the number of handles accumulates to a high value. Thread creation adds some memory pressure, but that does not force a GC until a sufficiently large handle count, and for some mostly idle apps, that can be very long. The same issue arises with directly starting threads as well.

Fixes dotnet/coreclr#6602:
- Track a dead thread count separately from the current dead thread count. This is the count that will contribute to triggering a GC, once it reaches a threshold. The count is tracked separately so that it may be reset to zero when a max-generation GC occurs, preventing dead threads that survive a GC due to references from contributing to triggering a GC again in this fashion.
- If the count exceeds a threshold, enumerate dead threads to see which GC generation the corresponding managed thread objects are in. If the duration of time since the last GC of the desired generation also exceeds a threshold, trigger a preferably non-blocking GC on the finalizer thread.
- Removed a couple of handles and some code paths specific to user-requested thread suspension, which is not supported on CoreCLR

Commit migrated from https://github.com/dotnet/coreclr/commit/2401b6ed08252d48831bfd804c3533cd0142c76c
12 files changed:
src/coreclr/src/debug/daccess/dacdbiimpl.cpp
src/coreclr/src/inc/clrconfigvalues.h
src/coreclr/src/vm/comsynchronizable.cpp
src/coreclr/src/vm/debugdebugger.cpp
src/coreclr/src/vm/eedbginterfaceimpl.cpp
src/coreclr/src/vm/finalizerthread.cpp
src/coreclr/src/vm/gcenv.ee.cpp
src/coreclr/src/vm/threads.cpp
src/coreclr/src/vm/threads.h
src/coreclr/src/vm/threadsuspend.cpp
src/coreclr/tests/src/baseservices/threading/DeadThreads/DeadThreads.cs [new file with mode: 0644]
src/coreclr/tests/src/baseservices/threading/DeadThreads/DeadThreads.csproj [new file with mode: 0644]