Pop quiz [memory usage]

Fawzi Mohamed fmohamed at mac.com
Sat Jun 6 14:47:33 PDT 2009


On 2009-06-06 21:07:40 +0200, Sean Kelly <sean at invisibleduck.org> said:

> Vladimir Panteleev wrote:
>> On Sat, 06 Jun 2009 20:19:45 +0300, Sean Kelly <sean at invisibleduck.org>
>> wrote:
[...]
>> 
>>> I've been debating for a while whether newCapacity shoulds exist at 
>>> all.   The GC already tends to leave free space at the end of blocks, 
>>> so why should the runtime second-guess it?
>> 
>> Do you mean at the end of pages, or pools?
> 
> Blocks.  Blocks less than 4k in the current allocator are sized in 
> powers of two, so array appends already get the "double in size" 
> behavior in Java even without newCapacity.  newCapacity just has the 
> potential to throw an array into the next larger block early, thus 
> potentially wasting more space if the array will never be appended to. 
> I think newCapacity isn't supposed to reserve extra space for blocks 
> larger than 4k, but it's been a while since I've looked at it.

at the moment the behavior is exactly the opposite (leaving the small 
array to the GC handling you just sketched)), only array larger than a 
page have the special treatment, I think that the idea is that 
appending to large arrays can be potentially very expensive, so those 
get the special treatment.
But as I said previously I don't fully understand the rationale, 
especially behind the idea of having more reserved space if the 
elements are larger, I could understand having the reserved space just 
referring to the elements, like this:

            long mult = 100 + 200L / log2plus2(newlength)
instead of
            long mult = 100 + 1000L / log2plus2(newcap)

or something in between

these give at most 1.5 or 1.71, so a waste of at most 100% or 71% and 
decreases as 1/log toward 1.02.

To really test this one should benchmark some "typical" applications.

The current choice is neither of these, I don't know exactly why this 
high weight to the high size elements. I think it is an error, but 
maybe there was an idea (at least for smallish sizes), that I don't see.

Fawzi

> 
>> If you mean that DMD will allocate memory pools larger than the immediate
>> memory requirement, that's true, however D's GC is "greedy" in that it
>> always allocates memory at the lowest address possible. This means that
>> when all previous pools fill up, the next object will "cap" the new array,
>> and the array will no longer be able to extend.
> 
> This is a quirk of the current GC.  A new GC may not behave the same 
> way (in fact I can guarantee that the one I'm working on is implemented 
> differently).
> 
>> So, I don't think that your idea is feasable with the current GC
>> implementation.
> 
> I'm not sure I understand.  The only "idea" I proposed was to get rid 
> of newCapacity.
> 
>> I wonder how much would things get improved if objects
>> would be divided between "growing" and "non-growing", with the GC
>> prioritizing allocating new objects in free space not directly following
>> "growing" objects.
> 
> The user already knows best which arrays are going to grow though.  Is 
> this really something the runtime should try to figure out?





More information about the Digitalmars-d mailing list