Dear Kira,
We discussed this question outside of community and I would like to add some information here for anyone interested in this item.
When assessing memory usage I would start the analysis by looking at memory within AIMMS:
https://how-to.aimms.com/Articles/170/170-memory-in-use.html
This guide can help identify which identifiers are taking up most memory and even the size of generated models. It does, on the other hand, not look at memory during a solve statement.
Another interesting article describes how to check memory in use at any moment.
https://how-to.aimms.com/Articles/134/134-Monitoring-Memory-Use.html
What I like about this article, is you can make use of the MemoryInUse which will consider total memory usage.
Another tips and tricks article have some good practices when you are running out of memory type situation.
https://how-to.aimms.com/Articles/108/108-kb08-reduce-memory-use.html
Finally, I might add that I normally use Windows programs to check memory usage of AIMMS. Several options here: Task Manager, Resource Monitor or Performance Monitor all come with Windows and can be very useful for this.
Best regards,
Dear Kira,
Here is some background which can be helpful in interpreting the output of the MemoryStatistics function.
Allocating memory from the OS and freeing it back to the OS when not used anymore, can be an expensive operation in terms of performance. Obviously, the more times AIMMS has to do this, the higher the impact on performance. Analyzing the way AIMMS typically allocates memory has shown that it allocates tiny bits of memory a lot of times, so this impacted the performance.
As a solution to this, we wrote a more efficient memory manager for AIMMS (many years ago). The basic idea behind this memory manager was to only allocate bigger blocks of memory from the system, and divide them up ourselves into smaller bits for the memory that AIMMS typically allocates. This ensures that relatively few allocations from the OS need to be made, which ensures a better performance.
That said, there is a tradeoff to be made: what do we consider small? And what large? Experimenting has shown us that allocations of less than 1KB of memory can be considered small. Therefore, AIMMS is programmed in such a way that if memory blocks smaller than this 1KB are requested, these are handled by our own memory manager. Blocks bigger than this are simply handled by the OS’s standard memory manager. It is this distinction that is reflected in the terms ‘small blocks’ and ‘system mallocs’ in the output of the MemoryStatistics function.
To explain things further, I have run the MemoryStatistics function on a small model. I will explain the output below.
SMALL BLOCK RELATED TOTALS
--------------------------
Number of mallocs performed for small blocks : 206838
This is the number of times a small block allocation has taken place, which was handled by our own memory manager.
Number of explicit frees performed for small blocks: 89540
This is the number of times such a small block has been freed again.
Number of bytes in small blocks allocated : 30.97Mb
This is the total number of (Mega)bytes of all 206838 small block allocations.
Number of bytes in small blocks explicitly freed : 22.19Mb
This is the total number of (Mega)bytes of all 89540 small block frees.
Current number of bytes allocated in small blocks : 8.77Mb
This is the above 30.97MB allocated minus the above 22.19MB freed bytes. So, the memory that the small blocks currently add up to.
Total memory allocated for small block use : 10.05Mb
This is the memory that was physically allocated from the system in order to store all the small block data. This was done in a small number of bigger blocks, which our memory manager internally divides up into smaller parts.
Percentage memory waste because of small block use : 12.72%
As you can see, 10.05MB was needed to store the current 8.77MB of small block data. So, to get a better performance, some memory ‘waste’ is allowed. In this case 12.72% of the 10.05MB. Small price to pay .
SYSTEM MALLOC RELATED TOTALS
----------------------------
Number of system mallocs performed : 4401
The number of allocations of blocks larger than 1KB, handled by the OS (i.e. not AIMMS itself).
Number of explicit system frees performed : 3443
The number of frees of blocks larger than 1KB.
Number of system bytes allocated : 10.22Mb
The total amount of memory of these 4401 allocations together.
Number of system bytes explicitly freed : 6.77Mb
The total amount of memory of these 3343 frees together.
Current number of system bytes allocated : 3.44Mb
The above 10.22MB minus the above 6.77MB.
Percentage small block allocations : 97.92%
This is a very interesting number: it shows us that no less than 97.92% of all allocations done by AIMMS are allocations of small blocks (smaller than 1KB).
Percentage allocations using system malloc : 2.08%
Obviously: 100% minus the above 97.92% is the percentage of bigger blocks directly from the OS.
Percentage bytes allocated in small blocks : 75.19%
In terms of bytes, the 97.92% of small blocks make up 75.19% of the total memory used.
Percentage bytes allocated using system malloc : 24.81%
So, 100% minus the above 75.19% makes 24.81% of memory allocated from the OS.
Number of large blocks allocated : 65
The number of bigger blocks that was allocated from the OS, in which the small block data was stored. As you can see, only 65 allocations from the OS were needed instead of 206838 separate allocations!
Number of large blocks freed : 0
None of these blocks have been freed to the OS yet. This is a disadvantage of our memory manager: if one of the 65 bigger blocks still stores even a single byte of small block data, it cannot be freed. Otherwise, this small block data would be lost.
Memory actually allocated from OS : 13.50Mb
Total memory allocated for small block use (10.05MB) plus current number of system bytes allocated (3.44MB).
Total memory actually requested : 41.18Mb
Number of bytes in small blocks allocated (30.97MB) plus number of system bytes allocated (10.22MB)
Number of garbage collects performed : 0
No garbage collection (i.e. re-shuffling the memory of small blocks in order to free up space; a costly operation in terms of performance, hence seldomly used).
Peak memory usage (net physical memory allocated) : 13.50Mb
The maximum amount of memory allocated from the OS so far.
Peak memory usage (really requested memory) : 12.22Mb
The amount of AIMMS data stored in that maximum amount of 13.50MB.
Contribution to peak net physical memory allocated : 100.00%
As the current amount of memory in this example is also the peak, this is 100.00%.
Contribution to peak really requested memory : 100.00%
As above.
Average number of bytes in small block requests : 156.99
The average number of bytes that AIMMS requested in the blocks smaller than 1KB and handled by our own memory manager.
Average number of bytes in system requests : 2434.48
The average number of bytes that AIMMS requested in the blocks bigger than 1KB and handled by the OS.
Average number of bytes in all requests : 204.44
The average number of bytes in all requests, be they small or large.
I hopes this provides more insight into the output of the MemoryStatistics function.
Kind regards,
Mischa Bronstring