Dan Feenberg of NBER wrote to me yesterday about a user whose code made repeated calls to my -boottest- module and apparently as a result was eating memory. He killed the process when it had taken 171 GB!
It appears to me that the problem is that my code creates object instances that point to each other. (One of the pointers is called "parent.") Mata's garbage collection strategy is based on reference counting. But that fails if two objects refer to each other, or if more complicated cycles are formed. So even if a Mata program creating the objects exits, and they should be destroyed, the memory does not get deallocated--not until you do "clear all."
As far as I know, this limitation isn't documented.
So the lesson is that your code should break reference loops before exiting. Here's a demo that will probably eat all the memory on your computer. WARNING: This will probably crash Stata and might crash your computer too.
If a new line is added at the end of test() to break the reference loops, "B.A.parent = NULL", then the problem goes away.
It appears to me that the problem is that my code creates object instances that point to each other. (One of the pointers is called "parent.") Mata's garbage collection strategy is based on reference counting. But that fails if two objects refer to each other, or if more complicated cycles are formed. So even if a Mata program creating the objects exits, and they should be destroyed, the memory does not get deallocated--not until you do "clear all."
As far as I know, this limitation isn't documented.
So the lesson is that your code should break reference loops before exiting. Here's a demo that will probably eat all the memory on your computer. WARNING: This will probably crash Stata and might crash your computer too.
Code:
clear all mata struct strA { pointer (class clsB scalar) scalar parent } class clsB { real matrix B struct strA scalar A void new() } void clsB::new() B = J(10000,10000,.) void test() { class clsB scalar B B.A.parent = &B } for (i=100;i;i--) test() end
If a new line is added at the end of test() to break the reference loops, "B.A.parent = NULL", then the problem goes away.
Comment