.net 3.0 For Windows Xp

0 views
Skip to first unread message

Kathrine Selvage

unread,
Aug 5, 2024, 7:37:03 AM8/5/24
to tipafise
Beforeinstalling my windows service in production, I was looking for reliable tests that I can perform to make sure my code doesn't contain memory leaks.However, All what I can find on the net was using task manager to look at used memory or some paid memory profiler tools.

Leaking references means you forget to set object references to null, or they never leave scope, and this is almost as likely to occur in Garbage collected languages as not - lists building up and not clearing, event handlers pointing to delegates, etc.


It's the GC equivalent of memory leaks and has the same result. This program tells you what references are taking up tons of memory - and you will know if it's supposed to be that way or not, and if not, you can go find them and fix the problem!


NOTE: You will likely have to run your app not as a service to use this. It starts first and then runs your app. You can do this with TopShelf or by just putting the guts in a dll that runs from an EXE that implments the service integrations (service host pattern).


Although managed code implies no direct memory management, you still have to manage your instances. Those instances 'claim' memory. And it is all about the usage of these instances, keeping them alive when you don't expect them to be.


Just one of many examples: wrong usage of disposable classes can result in a lot of instances claiming memory. For a windows service, a slow but steady increase of instances can eventually result in to much memory usage.


It is great to analyze memory leaks during development. It uses the concept of snapshots to compare new instances, disposed instances etc. This is a great help to understand how your service uses its memory. You can then dig deeper into why new instances get created or are kept alive.


Yes, you can test to confirm whether memory leaks are introduced.However, just out-of-the box this will not be very useful. This is because no one can anticipate what will happen during runtime. The tool can analyze your app for common issues, but this is not guaranteed.


Of course a memory profiler is the first kind of tool to try, but it will only tell you whether your instances keep increasing. You still want to know whether it is normal that they are increasing. Also, once you have established that some instances keep increasing for no good reason, (meaning, you have a leak,) you will want to know precisely which call trees lead to their allocation, so that you can troubleshoot the code that allocates them and fix it so that it does eventually release them.


Get in the habit of explicitly undoing everything that you do at the end of the scope of that thing which you are doing. For example, if you register an observer to the event of some observee, there should should always be some point in time (the disposal of the observer or the observee?) that you de-register it. In theory, garbage collection should take care of that by collecting the entire graph of interconnected observers and observees, but in practice, if you don't kick the habit of forgetting to undo things that you do, you get memory leaks.


Use IDisposable as much as possible, and make your destructors report if someone forgot to invoke Dispose(). More about this method here: Mandatory disposal vs. the "Dispose-disposing" abomination Disclosure: I am the author of that article.


Have regular checkpoints in your program where you release everything that should be releasable (as if the program is performing an orderly shutdown in order to terminate) and then force a garbage collection to see whether you have any leaks.


If instances of some class appear to be leaking, use the following trick to discover the precise calling tree that caused their allocation: within the constructor of that class, allocate an exception object without throwing it, obtain the stack trace of the exception, and store it. If you discover later that this object has been leaked, you have the necessary stack trace. Just don't do this with too many objects, because allocating an exception and obtaining the stack trace from it is ridiculously slow, only Microsoft knows why.


I do not agree that you can trust the Task Manager to check if you have a memory leak or not. The problem with a garbage collector is that it can decide based on heuristics to keep the memory after a memory spike and do not return it to the OS. You might have a 2 GB Commit size but 90% of them can be free.


You should use VMMAP to check during the tests what type of memory your process contains. You do not only have the managed heap, but also unmanaged heap, private bytes, stacks (thread leaks), shared files and much more which need to be tracked.


VMMap has also command line interface which makes it possible to create snapshots at regular intervals which you can examine later. If you have a memory growth you can find out which type of memory is leaked which needs depending on the leak type different debugging tooling approaches.


I would not say that the Garbage collector is infallible. There are times when it fails unknowingly and they are not so straight forward. Memory streams are a common cause of memory leaks. You can open them in one context and they may never even get closed, even though the usage is wrapped in a using statement (the definition of a disposable object that should be cleaned up immediately after its usage falls out of scope). If you are experiencing crashes due to running out of memory, Windows does create dump files that you can sift through.


Also, you want to turn off automatic tracking on Entity Framework where you are only reading and not writing. Best to isolate your writes, use a using() at this point, get a dbContext (with tracking on), write your data.


If you want to investigate what is on the heap. The best tool I've used is RedGate ANTS -gate.com/products/dotnet-development/ants-memory-profiler/solving-memory-problems/getting-started not cheap but it works.


However, by using the using() pattern where-ever you can (don't make a static or singleton DbContext and never have one context in a massive loop of updates, dispose of them as often as you can!) then you find memory isn't often an issue.


Unless you're dealing with unmanaged code, i would be so bold to say you don't have to worry about memory leaks. Any unreferenced object in managed code will be removed by the garbage collector, and the possibility in finding a memory leak within the .net framework i would say you should be considered very lucky (well, unlucky). You don't have to worry about memory leak.


However, you can still encounter ever-growing memory usage, if references to objects are never released. For example, say you keep an internal log structure, and you just keep adding entries to a log list. Then every entry still have references from the log list and therefore will never be collected.


From my experience, you can definitely use the task manager as an indicator whether your system has growing issues; if the memory usage steadily keep rising, you know you have an issue. If it grows to a point but eventually converges to a certain size, it indicates it has reached its operating threshold.


If you want a more detailed view of managed memory usage, you can download the process explorer here, developed by Microsoft. It is still quite blunt, but it gives a somewhat better statistical view than task manager.


Windows services are run under the control of the Windows Service Control Manager, which manages their lifetime. Therefore, they cannot be used as the primary process. However, Docker for Windows does allow you to install and run services in docker containers, as long as there is a primary process which keeps the container alive.


In the official Microsoft images microsoft/iis and microsoft/aspnet, a program called ServiceMonitor.exe is used as the primary process. This monitors the IIS service (w3svc) and stops itself (and therefore the container) when the service stops. In this way, it fulfils the first criterion in the list above. It also injects its own environment variables into the IIS process, thus fulfilling the second criterion. It does not try to fulfil the third. You can find the source code here. You can possibly adapt this.


However, this is not the perfect solution. Why do we create a Windows service? Probably because we want it to start without manual intervention, run as a different user, and sit in the background listening for requests. We can do all three using a container. But the container requires a regular executable.


So, I would probably begin by refactoring the actual functionality of your service into a separate class. Then, I would keep your Windows Service project (which should now have a Service class that uses your functionality class) for non-container use. And I would create a new console application, which uses the same functionality class, and use this console application as the ENTRYPOINT of a container.


HI All,

I am using .net framework 4.7 . I created GRPC server using console application. but it does not run on container . i f i run it manually its working .

So how can i run it with container on kubarnetes window server?

Please help me!


I have a Windows Service written in .NET running on a machine with the OneAgent installed. I can see the host and name of the service .EXE but cannot see any of the internals / processing or any of the external calls it makes.


You will need to make sure that the service .EXE is deep instrumented and if no services are detected out of the box, you will have to create custom services by defining the entry point class/method for transactions into the windows service. See link on how to set this up.


I have a user that is getting this pop and in my experience, windows.net has ben involved in alot a malicious activity. Is this expected with in IOS 17? We have never had this happen in any prvious versions. Thank you!


It's a 100% legitimate. If you just go ahead and click continue, you will see the standard microsoft exchange pop up for you to enter your username and password. It's just a re-login feature that you have to do when you transfer data to a new phone, etc.

3a8082e126
Reply all
Reply to author
Forward
0 new messages