Results 1 to 5 of 5

Thread: Memory usage

  1. #1

    Memory usage

    Code:
    procedure TForm3.Button1Click(Sender: TObject);
    const
      // 20 Items
      A: array [0..19] of Single = (
        0.5,  0.5, 0.5, 0.5, 0.5,
        0.5,  0.5, 0.5, 0.5, 0.5,
        0.5,  0.5, 0.5, 0.5, 0.5,
        0.5,  0.5, 0.5, 0.5, 0.5
      );
    
    var
      B: Array of Single;
      I: Integer;
    
    begin
      // 20 Items for B also
      SetLength(B, 20);
    
      // Ok just to make sure fill B with same
      for I := 0 to 19 do
        B[I] := 0.5;
    
      Log('SizeOf A: ' + IntToStr(SizeOf(A))); // -> 80
      Log('SizeOf B: ' + IntToStr(SizeOf(B))); // -> 8
    end;
    What is this? Why such a huge difference? I can't pass my dynamic array to something expecting the 'A' type.

  2. #2
    The reason why you are not getting the expected result is the fact that SizeOf is returning the size of a value type.
    Now when you are using static arrays then the value type is a static array itself.
    But when you are using dynamic arrays then the value type is actually a typed pointer (reference) to this dynamic array since dynamic arrays are referenced types. And since you were compiling 32 bit application the size of such pointer was 4 bytes (32 bit pointer). If you would be compiling this code into 64 bit application then the result would be 8 bytes (64 bit pointer) instead.

    So in order to get the size of dynamic array you actually need to calculate it from the number of items multiplied by the item size

    Code:
    Length(MyArray)*SizeOf(Element)
    Any way before you are starting to wonder about memory usage I strongly recommend you spend some time learning about what referenced types are and how they are managed by memory manager. This will help you better understand your programs memory usage so you will have better idea of where to focus first when doing any memory optimizations.

    EDIT: Oh and if you are interested in memory size of dynamic multidimensional arrays it becomes even more complicated. Why? Because in Pascal dynamic multidimensional arrays are actually arrays of arrays.

    Code:
    //Simple 2D dynamic array
    TwoDimensionalArray = array of array of Integer;
    Now what does this mean from memory management point stand of view.
    In first dimension you actually have array of pointers (references) to dynamic arrays. So the memory usage for this is Number of items in first dimension multiplied by the size of pointer (4 bytes in 32 bit applications or 8 bytes in 64 bit applications).
    Second dimension contains dynamic arrays whose size you can calculate with the code above.
    But bare in mind that in Pascal dynamic multidimensional arrays size of arrays in inner dimensions don't need to be the same.

    The code below shows you how you can manipulate the size of each inner array

    Code:
    var
      MultidimensionalArray: array of array of Integer;
    
    begin
      //2D array with 5 by 5 size
      SetLength(MultiDimensionalArray,5,5);
    
      //Such array could be represented like this
      {
      0 0 0 0 0
      0 0 0 0 0
      0 0 0 0 0
      0 0 0 0 0
      0 0 0 0 0
      }
    
      //But if we want we can adjust size of each inner array seperately
      Setlength(MultiDimensionalArray[0],1);
      Setlength(MultiDimensionalArray[1],2);
      Setlength(MultiDimensionalArray[3],3);
      Setlength(MultiDimensionalArray[4],2);
      Setlength(MultiDimensionalArray[5],1);
    
      //Visual representation of such array would actually loke like this
    
      {
      0
      0 0
      0 0 0
      0 0
      0
      }
    end;
    As you can see getting proper memory usage for dynamic multidimensional arrays can become quite problematic and grows more and more problematic with increase in the number of dimensions used.
    Last edited by SilverWarior; 11-07-2017 at 04:02 PM.

  3. #3
    I can't explain better. Good job!

  4. #4
    Yes, marvelous answer! Thank you!

    Although
    On 32 bit system
    A -> 80
    B -> 4 (4x8=32)

    On 64 bit system
    A -> 80
    B -> 8 (8x8=64)
    but that is besides the point. I now understand where the difference comes from.
    Last edited by Thyandyr; 11-07-2017 at 12:12 PM.

  5. #5
    You are correct. Size of pointer in 32 bit application is 4 bytes and in 64 bit application it is 8 bytes. That happens when you are writing your answer directly from your head (without checking the facts) at 12:21 AM

    I have edited my answer to correct that mistake.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •