How can we help you today? How can we help you today?
Andrew H
The memory profiler is really only designed for finding issues related to the amount of memory being used rather than performance issues with the garbage collector. It can help out a bit with these kinds of problem, though. Note that the % time in GC performance counter is quite hard to read, and a high value might not be telling you anything particularly useful. It's only updated after a garbage collection has taken place, and it represents the % of time spent in the most recent garbage collection relative to the amount of time since the preceeding collection. This means if you get a situation where two GCs happen in rapid succession and then nothing happens for a while, it will appear to read consistently high when in fact the garbage collector is having no impact on performance whatsoever. Because of the way this counter works, it's generally only indicating an issue if it's both giving a high value and changing frequently (meaning that there are a lot of expensive garbage collections occurring). If you're using server GC (which is the default for ASP.NET or things like Windows Services), a high value for this counter is quite likely as this garbage collector favours infrequent expensive collections and doesn't run concurrently. (This strategy reduces the overall time spent garbage collecting, but means that individual garbage collections may be more noticeable) Additionally, the memory profiler will push this value up, especially after you've taken a snapshot, as it performs housekeeping during .NET garbage collections (the more .NET rearranges memory during a garbage collection, the bigger this effect will be) If there is a genuine problem, there are really two things you can look at to improve performance. The first is to increase the speed at which a GC is completed. The time to perform a garbage collection is related to the number of objects that survive it, so the trick is to make sure as many objects get removed in one collection as possible. How you do this depends on the architecture of your application: generally if you have a long-lived object (like your main window, or a cache object), it's a good idea to make sure it nulls out references to more short-lived objects as soon as they're not going to be used any more. The memory profiler can find such dangling references for you. The second is to reduce the number of generation 2 garbage collections. If you're calling GC.Collect manually, you will probably be forcing generation 1 objects into generation 2 prematurely, so removing those may help (if you do have to call GC.Collect, do it only after dereferencing as much as possible, preferably in a callback when the application is idle). If you're not using GC.Collect, it gets a little more tricky: Objects on the Large Object Heap are often only collected during a full collection, so reducing the number of these that you are allocating will help (re-use old ones if possible, or allocate several small objects that don't end up on the LOH). This will also help with overall memory usage as the heap will get less fragmented. The memory profiler can identify which objects are on the LOH and what is referencing them. The hardest problem to fix is excessive promotion from generation 1. You can use the Generation 1 promoted bytes/sec performance counter to look for this problem: if it's high and GC time is high then what is probably happening is that the generation 1 garbage collections are occurring at the wrong time and a lot of stuff is getting put into generation 2 and being quickly dereferenced, which is pretty much the worse case scenario for the garbage collector. The memory profiler can identify what is in generation 1, so if you can take a snapshot at the appropriate moment you might get an idea of what is causing the problem, but there is an element of pot luck involved here. .NET should automatically increase the size of generation 1 when it detects this happening to make collections less frequent, so the problem is going to be some subtle interaction between your program and the garbage collector. / comments
The memory profiler is really only designed for finding issues related to the amount of memory being used rather than performance issues with the garbage collector. It can help out a bit with these...
0 votes
InquisitorJax wrote: When analysing the memory usage, the sum of the class list doesn't seem to add up to the private working set. Is it meant to? No: the totals for the class list will only add up to the total amount of memory used by live object instances. 'Private working set' could actually be less than this due to the way Windows manages working sets. 'Private bytes' will always be more, as in any .NET program the CLR itself will use some unmanaged memory, and .NET always allocates some memory to create new objects in. And if not - where is all the memory allocated that is not displayed? It will mostly be accounted for by unmanaged memory and memory that .NET has reserved but is not using yet. As you're profiling Silverlight, the memory used by Internet Explorer to display the page your application is on will account for a fair proportion of that space. The summary page gives an indication of how much free memory .NET has reserved but isn't using yet. You can also see this broken down by generation in the session overview tab. Also - the big indicator seems to me to be the column "Size with Children" on the instance list. It would be nice if this was more readily available in the summary page. Size with children is expensive to calculate, so this would be impractical for large applications. Additionally, it's calculated by simplifying the memory graph into a tree, which means it often won't reflect how the target application is working internally. The total value will add up to much more than the total memory being used by an application as objects will be referenced from more than one location. The class graph is designed to show how these relationships break down and help find what is referencing the most memory: if you start with a class using a lot of memory, you can use the graph to trace back from there to instances which will have a high 'size with children' value. / comments
InquisitorJax wrote: When analysing the memory usage, the sum of the class list doesn't seem to add up to the private working set. Is it meant to? No: the totals for the class list will only a...
0 votes
It means that you have an instance of SQL Server that hasn't got a registered ETW event provider. The event provider is implemented incorrectly in SQL Server, so it's not possible for ANTS to detect the real reason there's a problem. The most likely cause is that the instance is SQL Server Express: Microsoft turned off event tracing in that version, so ANTS can't profile it. The cheapest edition of SQL Server with this feature is the developer edition. You can have both Express and other versions of SQL Server installed, in which case ANTS will profile the other editions but will warn about the Express instance. If the installer failed to compile the etwcls.mof file for that instance of SQL Server, then you'll also get this error message. You'll find this file in the installation directory for the instance you're interested in (C:\Program Files\Microsoft SQL Server\MSSQL10.SQL2008\MSSQL\Binn, for example). You can install it by running 'mofcomp etwcls.mof'. I think this can also happen if the instance has been renamed at some point in the past. You'll need to edit the .mof file so that the description matches the new instance name (it's at the top, and should be '<instance name> Trace'. The other names don't actually matter. You can see the installed event providers by running the command 'logman query providers' from an admin command prompt. For any given SQL Server instance that isn't Express, there should be a '<instance name> Trace' entry. / comments
It means that you have an instance of SQL Server that hasn't got a registered ETW event provider. The event provider is implemented incorrectly in SQL Server, so it's not possible for ANTS to detec...
0 votes
If the iexplore process that ANTS starts gets shut down immediately for any reason then you'll see this behaviour. There are a few things that can cause this: Something I've seen is that sometimes IE starts running in the background, and passes any requests to its background instance. ANTS can't attach to this (in fact, it looks like the IE just shut down immediately), so you see this behaviour. The fix is to use task manager to ensure that no instances of iexplore are running before starting profiling. If IE goes into protected mode it restarts itself and disables the profiler. ANTS runs IE as an administrator on Vista to disable this behaviour, but you can also disable it explicitly in IE's preferences. You can see if this is happening by looking at the status bar. If the target web page closes the IE window/tab using javascript it can shut down the profiler as a result - the profiler can only target processes that it controls. Temporarily disabling this behaviour or using a different target page will prevent this (with IIS profiling you can use a different browser window, but with Silverlight profiling the profiler needs to attach to a specific instance of the browser in order to do its job) One other thing that might be worth trying is that if your application supports out-of-browser mode you can ask the profiler to specifically target the XAP file instead of a web page. / comments
If the iexplore process that ANTS starts gets shut down immediately for any reason then you'll see this behaviour. There are a few things that can cause this: Something I've seen is that sometimes ...
0 votes