Imp out-of-memory restarts

I’m getting some sporadic out-of-memory errors on the imp devices and would like to understand a little more about memory management on the devices.

The errors seem to be triggered by an append to a moderately sized array. When the error is posted in the device log, it always turns up about 12 seconds after I execute array.append(null).

The array itself is a cache of regularly requested requests from the agent. Each imp device can maintain a cache of up to 60 requests. Most of my imps have no more than 15 elements in the array at any one time. Each array element is either a null or a ~200 byte string. The device will occasionally extend the size of the array (usually by one element). In order to monitor the amount of device RAM free, I call imp.getmemoryfree() after every append and after every fetch from the cache.

As the cache fills, the amount of available RAM does fall, but not dramatically. I have seen out-of-memory errors occur even when imp.getmemoryfree() returns values of greater than 40K. If the amount of available RAM drops below 20K, the likelihood of a restart greatly increases.

So, I have a few questions:

Does Squirrel store the elements of an array contiguously? Or simply the references to those elements? If I append to the array, must Squirrel copy the entire array to a empty block that’s big enough to accommodate it?
Finally, how often is garbage collection undertaken? It’s possible that memory does become quite fragmented at times I’m extending the cache, as there’s a lot of object creation and deletion.


A Squirrel array is a contiguous block of references. (Except for array elements which are integers, bools or floats: those are stored directly in the array.) Appending to an array can cause an expensive re-allocation and copy, yes.

Squirrel objects are reference-counted: an object whose reference count goes to zero is de-allocated immediately. Because reference-counting schemes can be foxed by circular references, there’s also a traditional mark/sweep garbage collector which runs after every event handler. You don’t need to worry about the garbage collector if your structures don’t have circular references.


Thanks Peter, what about fragmentation? Will that be cleaned up during the garbage collection?

Currently garbage collection has no effect on fragmentation. In theory the Squirrel VM would have enough information to defragment the heap, but it’s a non-trivial task, especially doing so efficiently.