I'm not sure if the question title is the best one but it was the best one I could come up with...
I have this .NET (C#) applications which starts up with Windows and remains opened until the computer is turned off. The app stays on the tray and I open it by clicking the tray icon and close it the same way.
The app is not slow at first, it works normally, no problems there. But after long periods of inactivity of itself, it gets very slow when showing it again for the first time in a long period. Know what I mean.
For instance, I could not use/open (click the tray icon) for a few days and between those days I opened and closed and used lots of other apps, heavy apps too and I probably hibernated and resumed the computer a few times and when I needed to open my app again, it was slow. After a few minutes of using it, it goes back to normal and works fine.
I believe this has something to with memory management and the system probably frees up most of my app's memory so other programs can use it more efficiently. And maybe .NET memory management as something to do with it...
Whatever the reason, is there anything I can do to optimize my app regarding that issue?
This is almost certainly due to memory being paged out to disk.
When you cease using your application and other applications or tasks start exerting memory pressure, pages of memory from your app can be written out to disk. When you try to use your application again, all this data must then be read in causing the stalls that you see.
Unfortunately, there is no good solution - if you run as administrator or have the SeLockMemoryPrivilege, you can lock parts of your application into physical memory. You can try "touching" pages periodically to keep them in physical memory. Unfortunately, both these options will cause your application to interact badly with other applications on the system - your memory is getting paged out because the physical memory is needed for something else. You can attempt to lower your overall memory footprint, but you will still run into this issue in some cases. There are options for tweaking your working set size, but the OS is free to ignore those, and will in many cases.
You can use the .NET memory profiler to get a good idea of what your application is doing with memory over time. You can check if anything is building up where you don't expect it to (collections, lists, etc.) and causing your memory footprint to grow.
Have you tried double-clicking in Process Explorer on your running app and observe it for leaks? Is it CPU utilization, UI leak, memory leak, recurrent I/O?
If the issue is indeed that the program is being paged out due to an extended period of inactivity, have you tried setting a "keep-alive" timer, that fires every few minutes, that basically keeps the application in a state where the paging system doesn't ever see it as idle?
I reckon that this behavior is normal in Windows. Windows will serve the application that is need it most, ie, the application that is currently in used. Thus, if an application is minimized or not active for pro-long duration, like the case specified above, it will be the best candidate for Windows to page the application memory and make available memory to active application. Windows will restore the application memory when it get active from paging memory (hard disk), thus this explain why it is slow.
This might be not the best answer, but if I were you, I will experiment by increasing the base priority of the application. This can be done by using Thread object in .NET framework.
Thanks.
This isn't a root cause answer or solution, but if Michael is right and there's nothing you can really do about it, then you might just want to consider visually informing the user that your application is active with a progress bar or nifty progress circle.
It won't speed up your program, but it may ease the minds of your users just a little bit.
Related
Are there any tips, tricks and techniques to prevent or minimize slowdowns or temporary freeze of an app because of the .NET GC?
Maybe something along the lines of:
Try to use structs if you can, unless the data is too large or will be mostly used inside other classes, etc.
The description of your App does not fit the usual meaning of "realtime". Realtime is commonly used for software that has a max latency in milliseconds or less.
You have a requirement of responsiveness to the user, meaning you could probably tolerate an incidental delay of 500 ms or more. 100 ms won't be noticed.
Luckily for you, the GC won't cause delays that long. And if it did you could use the Server (background) version of the GC, but I know little about the details.
But if your "user experience" does suffer, it probably won't be the GC.
IMHO, if the performance of your application is being affected noticeably by the GC, something is wrong. The GC is designed to work without intervention and without significantly affecting your application. In other words, you shouldn't have to code with the details of the GC in mind.
I would examine the structure of your application and see where the bottlenecks are, maybe using a profiler. Maybe there are places where you could reduce the number of objects that are being created and destroyed.
If parts of your application really need to be real-time, perhaps they should be written in another language that is designed for that sort of thing.
Another trick is to use GC.RegisterForFullNotifications on back-end.
Let say, that you have load balancing server and N app. servers. When load balancer recieves information about possible full GC on one of the servers it will forward requests to other servers for some time therefore SLA will not be affected by GC (which is especially usefull for x64 boxes where more than 4GB can be addressed).
Updated
No, unfortunately I don't have a code but there is a very simple example at MSDN.com with dummy methods like RedirectRequests and AcceptRequests which can be found here: Garbage Collection Notifications
I have a serverside c# program running 24/7. After a few days the Processes 'Paged Pool' (as displayed in Windows Task Manager) is building up to 12 MB when it reaches 13-14 Mb the machine blue screens. The main 'Mem usage' is 180 mb,
I am running 32-bit Windows Server 2003 SP2.
The question is; What is the 'Paged Pool'? What in my C# program could be causing this?
Thanks
The Windows Paged Pool is a section of memory set aside by the Windows kernel for satisfying demands from the kernel and device drivers for memory which can be paged to disk, as opposed to memory which should never be paged to disk. (For an in-depth look, read: http://blogs.technet.com/b/markrussinovich/archive/2009/03/26/3211216.aspx)
I don't see how your process could be allocating Paged Pool, since it is managed by the kernel, however, given that you are getting a blue screen, there could be some connection. Are you using the Registry or Memory Mapped files at all? Those are big consumers of Paged Pool resources. Perhaps you are reading a lot of registry entries over the life of the process and never releasing them. However, as you can see from the above article, exhausing the paged pool won't blue screen, but perhaps you have a hardware device which is crashing on exhaustion.
Ultimately, you'd need to get more details about the problem, since a number of things could be going on here. Recording the Stop Error code, describing what the program does, etc., will all help in troubleshooting.
It sounds like you programme is acquiring memory and not releasing it.
Do you have an infinite loop running where objects that implement IDisposable are being created?
Check that they are being disposed of somewhere in the loop, either by calling Dispose on them directly, or wrapping them in a using block.
Can someone please explain to me why minimizing a windows app massively reduces the memory usage?
For example, I run Visual Studio showing 800MB memory usage in Task Manager then I minimize the Visual Studio app window and the memory usage now only shows 50MB in task manager. This seems to happen in all winforms apps.
From here:
What Task Manager shows as an application's memory usage is actually its working set. Windows trims the working set of an application when it is minimized, so that's why this figure goes down. The working set is not an accurate representation of how much memory an application is using.
In Windows Vista, Microsoft modified Task Manager to show private bytes instead (which is a much more useful figure), so this phenomenon doesn't occur anymore.
It's normal for applications not to be so aggressive about returning memory to the system. A computer doesn't run faster by having a lot of unused memory, so it's better to save the cleanup work until it's really needed.
When you minimise a program, the system sends a signal to it that it's time to return as much memory to the system as possible, so the program does a garbage collection and releases all memory that it can.
I've been experiencing a high degree of flicker and UI lag in a small application I've developed to test a component that I've written for one of our applications. Because the flicker and lag was taking place during idle time (when there should--seriously--be nothing going on), I decided to do some investigating. I noticed a few threads in the Threads window that I wasn't aware of (not entirely unexpected), but what caught my eye was one of the threads was set to Highest priority. This thread exists at the time Main() is called, even before any of my code executes. I've discovered that this thread appears to be present in every .NET application I write, even console applications.
Being the daring soul that I am, I decided to freeze the thread and see what happened. The flickering did indeed stop, but I experienced some oddness when it came to doing database interaction (I'm using SQL CE 3.5 SP1). My thought was that this might be the thread that the database is actually running on, but considering it's started at the time the application loads (before any references to the DB) and is present in other, non-database applications, I'm inclined to believe this isn't the case.
Because this thread (like a few others) shows up with no data in the Location column and no Call Stack listed if I switch to it in the debugger while paused, I tried matching the StartAddress property through GetCurrentProcess().Threads for the corresponding thread, but it falls outside all of the currently loaded modules address ranges.
Does anyone have any idea what this thread is, or how I might find out?
Edit
After doing some digging, it looks like the StartAddress is in kernel32.dll (based upon nearby memory contents). This leads me to think that this is just the standard system function used to start the thread, according to this page, which basically puts me back at square one as far as determining where this thread actually comes from. This is further confirmed by the fact that ALL of the threads in this list have the same value for StartAddress, leading me to ask exactly what the purpose is...?
Edit 2
Process Explorer let me to an actually meaningful start address. It looks like it's mscorwks.dll!CreateApplicationContext+0xbbef. This dll is in %WINDOWS%\Microsoft.NET\Framework\v2.0.50, so it looks like it's clearly a runtime assembly. I'm still not sure why
it's Highest priority
it appears to be causing hiccups in my application
You could try using Sysinternals. Process Explorer let's you dig in pretty deep. Right click on the Process to access Properties. Then "Threads" tab. In there, you can see the thread's stack and module.
EDIT:
After asking around some, it seems that your "Highest" priority thread is the Finalizer thread that runs due to a garbage collection. I still don't have a good reason as to why it would constantly keep running. Maybe you have some funky object lifetime behavior going on in your process?
I'm not sure what this is, but if you turn on unmanaged debugging, and set up Visual Studio with the Windows symbol server, you might get some more clues.
Might be the Garbage Collector thread. I noticed it too when I was once investigating a finalizer-related bug. Perhaps your system memory is low and the GC is trying to collect all the time? This was the case in the previously mentioned bug too. I couldn't reproduce it on my machine, but a co-worker of mine had a machine with less RAM where it would reappear like clockwork.
I know this is probably the canonical "It depends..." question but I'd appreciate any pointers as to where to start looking.
I have a client/server app talking over ethernet. In one computer I run the server and a client and on another just the client. One runs Vista and one runs XP. After an uptime of about 3 weeks the entire computer freezes and nothing works, not mouse, not keyboard, nothing -just power off. Every ten seconds the server sends a ping message to see if the clients are alive, other than that just a few small messages go back and forth every day.
I'm trying to find out if it's me causing it or something else. I've started a session and after a few days I thought I'd check for strange increases in memory use but beyond that I have very few ideas.
Some thoughts to consider:
You know the computer doesn't respond, but that doesn't mean it's hung. Does it respond to a ping?
Maybe the disk activity light is on all the time?
You say "no keyboard" - do you mean no caps lock or num lock lights?
Although the .NET application may be the only one you're running at the time, that does not imply it is the cause of the problem. Some background job could be doing it.
For example, I notice that Retrospect backup, when it is creating a snapshot, freezes the entire system for 10-15 minutes. I mean, no caps lock, the clock in the task bar doesn't update, no CTRL-ALT-DEL, can't type into an "Answer" text box in SO, nothing. It had nothing to do with what I was doing at the time, which was answering a question on SO.
After it came back, SO asked if I was a human. My feelings were hurt. ;-)
You could attach a kernel debugger to the OS. That way you should be able to inspect the state of the OS and your process even if the OS is completely unresponsive. (Unfortunately, it's a lot harder than just hitting "break" in VS. I suggest reading John Robbin's "Debugging Applications for .NET and Windows" before trying that.)
You could also try to create memory dumps of your application in regular intervals. You might have to do a little scripting for that, though. (usually, you'd create a dump with a keystroke, using a tool like userdump or adplus, but if the OS is not responding to keystrokes, that won't work.) That way, you know what state your process is in during or shortly before a hang.
This page: http://blogs.msdn.com/debuggingtoolbox/default.aspx is a good starting point for scripting WinDbg. (If you don't know what to do with a memory dump, I'd again suggest John Robbin's excellent book on debugging!)
Other than that, I can only think of standard debugging tricks: does the problem occur on every PC? Does it happen if there are no client requests? Does it happen sooner if there are more client requests? Does it happen sooner if there is less available physical memory? Try removing parts of your application (maybe on a separate server for testing) and see if the problem still occurs, and so on. Try running it in a VM so you can see if it uses the CPU, harddisk, or network during those "hangs".
This isn't going to be the answer, but I'd advise starting by checking your OS event logs and running a perfmon to keep track of memory, cpu usage etc.
Which computer freezes, the server or client? And what OSes are they running respectively?
As Daniel L noted, tight polling loops can really kill the CPU. If you can, change your code to use event handlers, it's a much more robust solution.
Finally, are you certain there's not a hardware problem on the freezing computer?