The Illimani mountain in La Paz, Bolivia
Metacello new
baseline: 'AllocationProfiler';
repository: 'github://jordanmontt/illimani-memory-profiler:main';
load.
Start Playing:
profiler := IllimaniAllocationProfiler new.
profiler
captureAllObjects;
profileFor: 5 seconds;
open
Example 1:
IllimaniAllocationProfiler new
classesToCapture: { ByteString . Array . String . OrderedCollection . ByteArray };
copyExecutionStack;
profileOn: [ 10000 timesRepeat: [ SpPresenter new ] ];
open
Example 2, capturing all but Morphic
morphicPackages := RPackageOrganizer default packages select: [ :package | package name includesSubstring: 'morphic' caseSensitive: false ].
morphicClasses := morphicPackages flatCollect: #classes as: Set.
profiler := IllimaniAllocationProfiler new
captureAllObjects;
classesToIgnore: morphicClasses;
profileFor: 5 seconds;
yourself.
profiler open
To use this profiler you need to specify which allocations you want to capture.
For that, you need to set the classes, of the allocations, that you want to capture.
You can capture all object allocations with the message captureAllObjects
or you can only capture a collection of classes classesToCapture: aCollection
.
It is also possible to copy the execution stack of each of the allocated objects with the message. This is very useful when you to make analysis, for example indentify in which context the allocations were prodoced, etc. Keep in mind that with a lot of allocations, copying the stack can cause the image to grow in size rapidly and making it slow to use.
profiler copyExecutionStack.
You can decide both to profile a given method block or just watching the activity of the image for some time.
"With this the profiler will block the ui and you will only capture the objects created by your code snippet"
profiler profileOn: [ anObject performSomeAction ].
"With this the profiler with not block the UI nor the image. So, you will capture all the allocations of the image"
profiler profileFor: 2 seconds.
For starting the stoping the profiling manually. This can be useful if you don't know how long your program will run.
profiler startProfiling.
profiler stopProfiling.
You can open the ui at any time with the message open
(even if the profiler is still profiling)
profiler open.
If you want to capture all the allocations of objects but ignoring some of them, you can use
profiler classesToIgnore: { ByteString . ByteArray }.
You can keep the allocated objects. This is useful is for example you want to know how many equal objects did you allocated. Note that this will affect the GC statistics since the GC will not be able to free memory since the objects are being referencered (!)
profiler keepTheAllocatedObjects.
Without the UI, because the profiler is independent from the UI, you can access to some statistics. See the protocol accessing - statistics
in the profiler to see the methods. Also, the profiler has a statistics model that groups and sorts the allocation by class and by methods. For example check 'profiler stats allocationsByClass.'
- Illimani uses method proxies library to capture the allocations. It insert a proxy in
Behavior>>basicNew:
andBehavior>>basicNew
. - Illimani also uses space and time to calculate the total size in memory of an object.
- It has an statistics model that helps with the calculations of allocations grouping them by classes and methods and sorting them by number of allocations.
- The UI is completly independent of the profiler. It can be used without it. You will have access to all allocations and to the same statistics.
Observations:
- Profile the profiler :p for big arrays the presenters and the visualizations take a long time to open
- I now, it does not have enough tests. My inmidiate next tasks is to add good tests.