Re: The problems arrayed before me...

From: Rob Kennedy (.)
Date: 12/06/03

  • Next message: Christakis John: "Re: The problems arrayed before me..."
    Date: Sat, 06 Dec 2003 00:35:41 -0600
    
    

    Christakis John wrote:
    > When an array is grown, how does Delphi manage this cleanly?

    Delphi uses the ReallocMem function to do the grunt work. With the
    default memory manager, the first thing it tries to do, when it receives
    a request for a larger piece of memory, is to check whether the existing
    allocated block is actually already large enough for the new request.
    When you ask for a certain amount of memory, the memory manager is free
    to allocate more than you ask for, and it keeps track of that. The
    reallocation is then as simple as updating the size field and giving you
    back the same buffer you started with.

    When the existing buffer isn't large enough for the new request, then
    the memory manager will try to find a better fit from the other memory
    blocks it has at its disposal. When you free something, that memory
    isn't immediately returned to the OS; Delphi will keep it to reuse
    later. If the memory manager still doesn't have any blocks large enough
    for the new request, it asks for another chunk of memory from the OS. If
    that _still_ doesn't work, then you're out of memory.

    Once the memory manager has the new lareg block, it copies the contents
    of the old block into the new one and marks the old buffer as freed.

    Dynamic arrays are stored as pointers to the element data. If you have a
    two-dimensional dynamic array, 6x10, the master array will only be 24
    bytes long -- long enough to hold six four-byte pointers. It doesn't
    matter how long any of the 10 subarrays are. When you resize the master
    array, the subarrays are not duplicated. Only their pointers are copied
    from the old array to the new one.

    > and that code is repeated an unknown amount of times. But, where is Delphi
    > putting all this data? It cannot be contiguous, can it - does that matter?
    > Could this cause the 'Out of Memory' errors I am getting on large array
    > sizes? Would this cause the equivalent of disk fragmentation in memory?

    Fragmentation is exactly what happens. With the memory manager
    allocating progressively larger buffers each time, it abandons a
    slightly smaller one. It won't always be able to use that discarded
    space for anything else, but it can't return it to the OS, either, since
    other parts of the large block from the OS are still being used. So even
    if you have lots of unused memory, it may still report that you're out
    of memory since it's all in small portions. (Like Monty Python have
    122,000 miles of string in three-inch lengths.)

    > I can't just set the length to a figure larger than I think it
    > will be as there is no way to tell how big it could get. I could end up
    > allocating more memory than the machine has.

    A common technique for dynamic memory allocation is to only increase the
    array's size occasionally. Not for every iteration, but not just once at
    the beginning, either. Allocate a reasonable size at the start, and when
    you exhaust that, grab another group. You can see this in action in the
    implementations of TList and TStringList. And that leads me to my next
    suggestion. Instead of using the master array by itself, wrap access to
    it into a class. Then the class can manage the storage and allocation
    details.

    Since your subarrays aren't stored contiguously, your master array might
    not need to be contiguous, either. You could keep the master array in
    segments. Have an array of fixed-size segments. When you have enough
    subarrays to fill a segment, add another.

    -- 
    Rob
    

  • Next message: Christakis John: "Re: The problems arrayed before me..."

    Relevant Pages

    • Re: Another C# marshaling question
      ... // Get the pointer of the location in memory. ... > public static extern int FF_Function( ... > // Allocate the array. ...
      (microsoft.public.dotnet.languages.csharp)
    • Re: INTENT(WORKSPACE) as a new Fortran feature?
      ... >> the array once in the caller than each time within the subroutine. ... > the stack pointer is being changed to allocate local variables in any ... "actual" memory would never be touched at all. ... If, on a particular machine, the compiler knows that it would be ...
      (comp.lang.fortran)
    • Re: Storing the size of an array in the structure itself
      ... >> I think every C programmer can relate to the frustrations that malloc ... >> the size of an array must be stored separately to be a nightmare. ... is anything more than just that - a chunk of memory. ... > Otherwise you couldn't tell it how much to allocate. ...
      (comp.lang.c)
    • Re: Creating a logical matrix in a mex-file
      ... Then use mxMalloc to allocate the memory ... Use mxSetData to set the data of the array to the ... This would avoid the initialization of the memory. ...
      (comp.soft-sys.matlab)
    • Re: Fast string operations
      ... Looping: I thought looping over arrays in managed code was "slow" ... array handling and such. ... The problem with TrimHelper is that it always returns a new string instance. ... The customer perceives this as a memory leak. ...
      (microsoft.public.dotnet.languages.csharp)