.NET Windows Service, threads and garbage collection (possible memory leaks)
I am developing a .NET Windows service that is creating a couple of threads and then uses these threads to send print jobs to printers (there is a thread for each printer). I have some issues which sometimes can be fixed by restarting the service. Some issues also arise when the service has been 开发者_JS百科running for a while. This makes me suspect a possible memory leak. So, a couple of questions:
Would a garbage collector collect an object if it was created inside a thread, or will the object exist until the thread is stopped/terminated?
What tools can I use to monitor the amount of memory used by a Windows service and by a thread that I am starting programmatically?
All objects are created inside threads. Every instruction ever executed is within a thread. Objects will be garbage collected at some point after there are no live references to them. Objects don't "belong" to the thread they were created on.
For monitoring the service, you can use perfmon
which has plenty of counters for things like garbage collection. For more detailed analysis of where you may be leaking objects, you should use a profiler. All of this is likely to be made simpler if your program can also run as a non-service. (You may want to separate it out into a "launcher" part and then a library which can be used either from the service or from a console application.)
You should track down your memory leak.
The .NET garbage collector frees up the memory held by objects that are no longer "reachable". To discover which objects are "reachable" (and therefore not yet eligible for garbage collection) the GC pauses all threads, starts with a set of "root" objects and attempts to walk the full graph. Every object that is not marked as reachable becomes a candidate for garbage collection. It makes no difference which thread was active when the memory was initially allocated; all that matters is that your object is no longer reachable during the first phase of garbage collection. The "roots" include all local variables and method parameters (these are the variables in the stack for each of your service's threads) and static variables.
Microsoft has a free download called Debugging Tools for Windows, which includes windbg.exe. This tool can be used to create a dump of your process's (private) memory. You can invoke it like this: windbg.exe -p <processID>
The tool (with the help of the SOS extension) allows you to navigate the reachable objects yourself. If your problem lies with a surfeit of reachable managed objects, the tool should be able to help.
精彩评论