Smalltalk and large images
Periodically, I get asked about using VisualWorks in large memory situations. In the sense I'm discussing it, this means more than a gigabyte. If you need to set up a VW image that is going to use more than that amount of RAM in a runtime situation, you are going to have to get into the guts of the MemoryPolicy system. The first thing you'll want to do is read the documentation - it's pretty well covered there. After that, you'll need to have a look at a few places. The place to start is class MemoryPolicy. It turns out the ObjectMemory is managed, in large part, by settings in the current memory policy. As the class comment puts it:
This class contains a class variable called CurrentMemoryPolicy which contains a reference to the currently active memory-policy object. Control is passed to the CurrentMemoryPolicy during the idle loop and during the low-space condition for the appropriate response. This class also relies on the CurrentMemoryPolicy to specify a hard and soft low-space limit. The HardLowSpaceLimit is meant to represent an emergency low-space condition, and the SoftLowSpaceLimit is a secondary threshold that the CurrentMemoryPolicy can use to gain control in advance of the hard limit. This class arranges for control to be passed to the CurrentMemoryPolicy whenever either of these two limits is exceeded. See the comments in the class MemoryPolicy for further details regarding the role that a memory policy is expected to play.
This is why you have to modify MemoryPolicy if you have an application that will use "large" amounts of RAM - the basic policies aren't going to work. For our purposes, here's the core method that will interest you in MemoryPolicy: #favorGrowthOverReclamation. This method is invoked whenever the system needs more space for new objects - it has to decide, based on the current policy, whether to ask the OS for more RAM, or whether to do a GC and hope some space clears up. Here's the basic implementation:
favorGrowthOverReclamation "Answer true if we want to react (at this point in time) to the low-space condition by growing memory rather than reclaiming memory." ^growthRegimeMeasurementBlock value <= growthRegimeUpperBound
growthRegimeUpperBound is set to 32MB by default - likely not what you want! It's better than the pre-7.1 setting of 16MB, but not suitable for the situation we are discussing. The block being referenced looks like this:
[ObjectMemory dynamicallyAllocatedFootprint] or [ObjectMemory growthDuringCurrentSession]
What that's going to do is cap the maximum growth of memory for the Smalltalk application. You'll likely want to adjust that block based on your application and deployment situation. Another place you'll want to look is the amount of RAM that system allocates when it does allocate - which is controlled by the preferredGrowthIncrement variable. By default, this is set to 1 MB - you'll likely want it bigger. How do you do this? Here are the steps:
- Define a new subclass of MemoryPolicy. Make sure to implement the #setDefaults method, invoke the superclass version, and set the values of the appropriate variables.
- Install the policy like this: ObjectMemory installMemoryPolicy: MyMemoryPolicy new setDefaults
I've published an example implementation in the public store. The #favorGrowthOverReclamation method there looks like this:
favorGrowthOverReclamation ^self memoryStatus availableFreeBytes <= self growIfFreeBytesLessThan
Where growIfFreeBytesLessThan is a new variable setting. It's the floor for how much available RAM the image ought to have. Be Careful!! with this strategy - this method puts no ceiling on image growth. If the OS allows you to limit that, or there are other application specific factors that make this "not a problem", go ahead - but you'll likely want to think long and hard about this one.
In any case, this ought to get you started. To take a look at the example Memory Policy, look at package LargeMemoryPolicy in the public store. It installs itself as the new memory policy on load, as follows:
ObjectMemory installMemoryPolicy: LargeMemoryPolicy new setDefaults
Questions? Send them my way

