Monitoring memory usage
Since ILNumerics.Net is highly integrated into the .NET framework, all the tools available for performance measures can be utilized for your application also. We will briefly describe the most common of them and take a more closer look into the tools which are inherent part of ILNumerics.Net and specialized for monitoring ILNumerics.Net applications.
Performance monitor - PerfMon
On systems running Microsoft WindowsR operating systems, the performance monitor can be used to display information about the .NET runtime state.
The tool is started by Start -> Run -> perfmon. Delete the default performance indicators and add the indicators from the CLR. This is done by actvating the 'plus' toolbar
button. Select '.NET CLR memory' from the data object list. If you are in a debug session or the application you are about to measure is already running, select it on the instances list. This
will filter and display only informations related to a specific application.
The following indicators may be of interest to you:
- Number of bytes in the heap
- Large object heap size
- Number of garbage collector runs
- Finalization survivors
Each indicator comes with a short informative description which is displayed by activating the corresponding button in the "Add indicator" window. In order to scale each indicator output a scaling factor can be applied to each graph. This factor is accessible via the current indicator list.
Performance explorer tools in MicrosoftR Visual Studio IDE
Microsoft Visual Studio provides a performance profiler/ monitor suite. This may conveniently be used to count the calls an application does to specific functions and/or the number of objects allocated by specific members. Consult the IDE documentation in order to start using such profiling monitors.
Utilizing ILNumerics.Net memory pool
In the last article Memory management for ILNumerics.Net the class ILMemoryPool has been introduced. This class offers the
following interface member to monitor memory usage:
ReclaimedBytesCount |
Number of bytes reclaimed from pool since the pool was created or reset the last time. |
ReclaimedObjectsCount |
Number of objects reclaimed from pool since the pool was created or reset the last time. |
Info() |
Returns string with full infos about the pools content. The objects currently restisting inside the pool are listed in order of their size. |
Info(bool) |
Alternatively return a short version (one line) with the most important infos about the pools content only:
|
Info(bool,bool) |
Same purpose as function Info(bool) with the possibility to reset internal counters of reclaimed objects. |
The Info(bool) function enables memory pool state display for situations where an abreviated version (i.e. 'one line' height) is needed. Examples are the
debugger watch window or a user defined formated console debug output. This picture shows a single lined memory pool display output in a watch expression in Visual Studio 2005:
Debugger watch expression showing single lined memory pool info. Only the most important infos are shown.
The next figure shows a full memory pool info output. Such output can get used in user defined console or log file debugging outputs or in the output of multi-line capable debug tools like the ILArrayWatch AddIn. This tool comes with ILNumerics.Net, integrates smoothly into Visual Studio 2005 and is free of charge and use.
Multi line debugger output showing memory pool content also.
How are the informations of full memory pool output to be interpreted? After a line displaying the time of state display the short info line follows. Then a list of arrays currently hold in the pool follows. The list is sorted by increasing size of the array objects. Each line starts with the length and than prints abbreviations for each object contained with that length. The objects are displayed in the order of their incoming into the pool - oldest objects come first.
How are the abreviations to be interpreted? The tokens always have 2 letters or digits reflecting the underlying system type of the elements of the array. If the name of the type does not end with a number (such in Int32 or UInt16), the first 2 letters are displayed (Do = "Double", By = "Byte", fc = "fcomplex" ...). If the name ends with a number, the token displays the first letter and the last digit. Therefore the actual name can always get derived from the token.
The monitoring methods utilizing ILMemoryPool itself introduce a small performance hit. Therefore they should be used for debugging and profiliing issues only. However the overhead for querying the public counter member is relatively small compared to the overhead for calling the Info() function.