Recent

Author Topic: Memory used  (Read 3115 times)

Eduards

  • New Member
  • *
  • Posts: 27
Memory used
« on: February 24, 2017, 10:22:20 pm »
Hi,

I show 180 small images (360x180px, 2.5-3 kb png files) with mouse over event. I load them all into TImageList on FormCreate event (which takes some 4-5 seconds to load), and later show them with
Code: Pascal  [Select][+][-]
  1.     Image.Visible := True;
  2.     ImageList.GetBitmap(i, Image.Picture.Bitmap);
.

Since implementation of this feature memory usage for my application in Task Manager have gone up to 480 MB. I am wondering if working with dynamic array of bitmaps would be faster and took less memory? There are no leaks.
« Last Edit: February 24, 2017, 10:24:00 pm by Eduards »

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Memory used
« Reply #1 on: February 26, 2017, 05:01:16 pm »
Hi,
are you sure there is nothing wrong anywhere ???
I did this... just for fun: 180 pics (TImage) 360x360 PNG Size: 68,8 kb

Result: 117 MB RAM (TaskManager)
EDIT: Funny... if I scroll down then it is 200 MB...

Code: Pascal  [Select][+][-]
  1. Unit Unit1;
  2.  {$MODE OBJFPC}{$H+}
  3.  
  4. Interface
  5.  USES
  6.   Classes,  SysUtils, Forms,
  7.   Controls, ExtCtrls, Dialogs;
  8.  
  9.  TYPE
  10.   TForm1 = Class(TForm)
  11.  
  12.    Procedure FormCreate   (Sender: TObject);
  13.    Procedure FormKeyDown  (Sender: TObject; Var Key: Word;
  14.                            Shift : TShiftState);
  15.    Procedure ArrangeImages;
  16.  
  17.   End;
  18.  
  19.  VAR
  20.   Form1: TForm1;
  21.  
  22. Implementation
  23.  {$R *.LFM}
  24.  
  25.  
  26. Procedure TForm1.ArrangeImages;
  27.   Var
  28.    i  : Integer;
  29.    pic: TImage;
  30.  
  31.    myTop,
  32.    myLeft,
  33.    countLeft,
  34.    countTop,
  35.    imgWidth,
  36.    imgHeight: Integer;
  37.  Begin
  38.   imgWidth  := 360;
  39.   imgHeight := 360;
  40.   countLeft :=   0;
  41.   countTop  :=   0;
  42.   myTop     :=   0;
  43.   myLeft    :=-360;
  44.  
  45.    For i:= 1 To 180
  46.    Do
  47.     Begin
  48.      myLeft:= myLeft+imgWidth;
  49.  
  50.       If (ClientWidth-(countLeft*imgWidth)) < imgWidth
  51.       Then
  52.        Begin
  53.         myLeft   := 0;
  54.         myTop    := myTop+imgHeight;
  55.  
  56.         countLeft:= 0;
  57.         countTop := countTop+1;
  58.        End;
  59.  
  60.      pic:= TImage.Create(Self);
  61.      pic.SetBounds(myLeft, myTop, imgWidth, imgHeight);
  62.      pic.Picture.LoadFromFile('I:\(DOWNLOADS)\OK.png');
  63.      pic.Parent:= Self;
  64.      pic.Show;
  65.  
  66.      countLeft:= countLeft+1;
  67.     End;
  68.  End;
  69.  
  70.  
  71. Procedure TForm1.FormCreate(Sender: TObject);
  72.  Begin
  73.   DoubleBuffered:= True;
  74.  
  75.   SetBounds(0, 0, Screen.WorkAreaWidth, Screen.WorkAreaHeight);
  76.   ArrangeImages;
  77.  End;
  78.  
  79.  
  80. Procedure TForm1.FormKeyDown(Sender: TObject; Var Key: Word;
  81.                              Shift : TShiftState);
  82.   Var
  83.    i, iCount: Integer;
  84.  Begin
  85.   If Key = Ord('R')
  86.   Then
  87.    Begin
  88.     iCount:= 0;
  89.  
  90.     For i:= 0 To ComponentCount-1
  91.     Do
  92.      Begin
  93.       If Components[i] Is TImage
  94.       Then iCount:= iCount+1;
  95.      End;
  96.  
  97.     ShowMessage(IntToStr(iCount));
  98.    End;
  99.  End;
  100.  
  101. End.
  102.  

BTW: What about TMemoryStream and drawing the pics ??? No TImages...
« Last Edit: February 26, 2017, 05:13:55 pm by RAW »
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Memory used
« Reply #2 on: February 26, 2017, 10:40:49 pm »
This one has exactly the same size: 117 MB (TaskManager)
So it saves me 83 MB if I don't draw all at the same time...

Maybe an array is faster then a TMemoryStream... ?
Code: Pascal  [Select][+][-]
  1. Unit Unit1;
  2.  {$MODE OBJFPC}{$H+}
  3.  
  4. Interface
  5.  USES
  6.   Classes,  SysUtils,
  7.   Controls, Graphics,
  8.   Forms;
  9.  
  10.  TYPE
  11.   TForm1 = Class(TForm)
  12.  
  13.    Procedure FormCreate (Sender: TObject);
  14.    Procedure FormPaint  (Sender: TObject);
  15.    Procedure FormClose  (Sender: TObject; Var CloseAction: TCloseAction);
  16.  
  17.    Procedure ShowPics;
  18.  
  19.     PRIVATE
  20.      arrPics: Array[1..180] Of TPicture;
  21.   End;
  22.  
  23.  VAR
  24.   Form1: TForm1;
  25.  
  26. Implementation
  27.  {$R *.LFM}
  28.  
  29.  
  30. Procedure TForm1.FormCreate(Sender: TObject);
  31.   Var
  32.    i, iCount: Integer;
  33.  Begin
  34.   DoubleBuffered:= True;
  35.   SetBounds(0, 0, Screen.WorkAreaWidth, Screen.WorkAreaHeight);
  36.   WindowState:= wsMaximized;
  37.   iCount:= 0;
  38.  
  39.    For i:= 1 To 180
  40.    Do
  41.     Begin
  42.      Inc(iCount);
  43.  
  44.      arrPics[i]:= TPicture.Create;
  45.       If iCount = 2
  46.       Then
  47.        Begin
  48.         arrPics[i].LoadFromFile('I:\(Downloads)\OK2.png');
  49.         iCount:= 0;
  50.        End
  51.       Else arrPics[i].LoadFromFile('I:\(Downloads)\OK.png');
  52.     End;
  53.  End;
  54.  
  55.  
  56. Procedure TForm1.ShowPics;
  57.   Var
  58.    i: Integer;
  59.  
  60.    myTop,
  61.    myLeft,
  62.    countLeft,
  63.    countTop,
  64.    imgWidth,
  65.    imgHeight: Integer;
  66.  Begin
  67.   imgWidth := 360;
  68.   imgHeight:= 360;
  69.   countLeft:=   0;
  70.   countTop :=   0;
  71.   myTop    :=   0;
  72.   myLeft   :=-360;
  73.  
  74.  
  75.    For i:= 1 To 15 // only draw the viewable pics
  76.    Do
  77.     Begin
  78.      myLeft:= myLeft+imgWidth;
  79.  
  80.       If (ClientWidth-(countLeft*imgWidth)) < imgWidth
  81.       Then
  82.        Begin
  83.         myLeft   := 0;
  84.         myTop    := myTop+imgHeight;
  85.  
  86.         countLeft:= 0;
  87.         countTop := countTop+1;
  88.        End;
  89.  
  90.      Canvas.Draw(myLeft, myTop, arrPics[i].Graphic);
  91.  
  92.      countLeft:= countLeft+1;
  93.     End;
  94.  End;
  95.  
  96.  
  97. Procedure TForm1.FormPaint(Sender: TObject);
  98.  Begin
  99.   ShowPics;
  100.  End;
  101.  
  102.  
  103. Procedure TForm1.FormClose(Sender: TObject; Var CloseAction: TCloseAction);
  104.   Var
  105.    i: Integer;
  106.  Begin
  107.   For i:= Low(arrPics) To High(arrPics)
  108.   Do arrPics[i].Free;
  109.  End;
  110.  
  111. End.
  112.  
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

RAW

  • Hero Member
  • *****
  • Posts: 868
Re: Memory used
« Reply #3 on: February 27, 2017, 09:25:26 pm »
Hmmm... funny ..
If I use layered windows (180) and load 180 pics (360x360, 68,8kb) in a static array, then the Result is 112 MB.
That's interesting... 180 pictures as layered windows are smaller than 15 drawn pics...
Maybe the TaskManager is drunk ??? Or What ???

EDIT: If I don't load the 180 pics and only create 180 layered-window-pics then the Result is 5 MB in RAM (5.636 kb).
And I can scroll up and down all the 180 "pics". That's strange...

If you are using WINDOWS then use "layered-window-pics".   :P
Code: Pascal  [Select][+][-]
  1. Unit uTEST;
  2.  {$MODE OBJFPC}{$H+}
  3.  
  4. Interface
  5.  USES
  6.   Windows, Classes,  SysUtils,
  7.   Forms,   Controls, Graphics;
  8.  
  9.  Type
  10.   TForm1 = Class(TForm)
  11.  
  12.    Procedure FormCreate  (Sender: TObject);
  13.    Procedure FormClose   (Sender: TObject; Var CloseAction: TCloseAction);
  14.    Procedure FormKeyDown (Sender: TObject; Var Key: Word; Shift: TShiftState);
  15.  
  16.     PRIVATE
  17.      arrPics: Array[1..180] Of TPicture;
  18.      arrWnds: Array[1..180] Of TForm;
  19.  
  20.      bfBlend: TBlendFunction;
  21.      pPos   : TPoint;
  22.      size   : TSize;
  23.      dwStyle: DWORD;
  24.   End;
  25.  
  26.  VAR
  27.   Form1: TForm1;
  28.  
  29.   Function UpdateLayeredWindow(
  30.             hWnd: HWND; hdcDst: HDC; pptDst: PPoint; pSize: PSize;
  31.             hdcSrc: HDC; pptSrc: PPoint; crKey: TColor; pBlend:
  32.             PBlendFunction; dwFlags: DWORD): BOOL;
  33.             StdCall; External 'user32';
  34.  
  35. Implementation
  36.  {$R *.LFM}
  37.  
  38.  
  39. Procedure TForm1.FormCreate(Sender: TObject);
  40.   Var
  41.    iCount, i,
  42.    myTop, myLeft,
  43.    countLeft, countTop,
  44.    wndWidth, wndHeight: Integer;
  45.  
  46.    pic: TPicture;
  47.  Begin
  48.   Height:= 360;
  49.   Width := 360;
  50.  
  51.   wndWidth := 360;
  52.   wndHeight:= 360;
  53.   countLeft:=   0;
  54.   countTop :=   0;
  55.   myTop    :=   0;
  56.   myLeft   :=-360;
  57.  
  58.   iCount:= 0;
  59.  
  60.    For i:= 1 To 180
  61.    Do
  62.     Begin
  63.      Inc(iCount);
  64.  
  65.      arrPics[i]:= TPicture.Create;
  66.       If iCount = 2
  67.       Then
  68.        Begin
  69.         arrPics[i].LoadFromFile('I:\(Downloads)\OK2.png');
  70.         iCount:= 0;
  71.        End
  72.       Else arrPics[i].LoadFromFile('I:\(Downloads)\OK.png');
  73.     End;
  74.  
  75.   pic:= TPicture.Create;
  76.    Try
  77.     pic.LoadFromFile('I:\(Downloads)\OK(pre).png');
  78.  
  79.      For i:= 1 To 180
  80.      Do
  81.       Begin
  82.        myLeft:= myLeft+wndWidth;
  83.  
  84.         If (Screen.WorkAreaWidth-(countLeft*wndWidth)) < wndWidth
  85.         Then
  86.          Begin
  87.           myLeft   := 0;
  88.           myTop    := myTop+wndHeight;
  89.  
  90.           countLeft:= 0;
  91.           countTop := countTop+1;
  92.          End;
  93.  
  94.        arrWnds[i]:= TForm.Create(Application);
  95.        arrWnds[i].SetBounds(myLeft, myTop, wndWidth, wndHeight);
  96.        arrWnds[i].Show;
  97.  
  98.        dwStyle:= GetWindowLongA(arrWnds[i].Handle, GWL_EXSTYLE);
  99.         If (dwStyle And WS_EX_LAYERED = 0)
  100.         Then
  101.          Begin
  102.           SetWindowLong(arrWnds[i].Handle, GWL_EXSTYLE, dwStyle Or
  103.                         WS_EX_LAYERED);
  104.  
  105.            pPos:= Point(0, 0);
  106.            size.cx:= pic.Width;
  107.            size.cy:= pic.Height;
  108.  
  109.            bfBlend.BlendOp            := AC_SRC_OVER;
  110.            bfBlend.BlendFlags         := 0;
  111.            bfBlend.SourceConstantAlpha:= 255;
  112.            bfBlend.AlphaFormat        := AC_SRC_ALPHA;
  113.  
  114.            UpdateLayeredWindow(
  115.             arrWnds[i].Handle, 0, Nil, @size, pic.Bitmap.Canvas.Handle,
  116.             @pPos, 0, @bfBlend, ULW_ALPHA);
  117.          End;
  118.         countLeft:= countLeft+1;
  119.       End;
  120.    Finally
  121.     pic.Free;
  122.    End;
  123.  End;
  124.  
  125.  
  126. Procedure TForm1.FormClose(Sender: TObject; Var CloseAction: TCloseAction);
  127.   Var
  128.    i: Integer;
  129.  Begin
  130.   For i:= Low(arrPics) To High(arrPics)
  131.   Do arrPics[i].Free;
  132.  End;
  133.  
  134.  
  135. Procedure TForm1.FormKeyDown(Sender: TObject; Var Key: Word;
  136.                              Shift : TShiftState);
  137.   Var
  138.    i: Integer;
  139.  Begin
  140.   If Key = VK_UP
  141.   Then
  142.    Begin
  143.     For i:= Low(arrWnds) To High(arrWnds)
  144.     Do arrWnds[i].Top:= arrWnds[i].Top-20;
  145.    End;
  146.  
  147.  
  148.   If Key = VK_DOWN
  149.   Then
  150.    Begin
  151.     For i:= Low(arrWnds) To High(arrWnds)
  152.     Do arrWnds[i].Top:= arrWnds[i].Top+20;
  153.    End;
  154.  End;
  155.  
  156. End.
  157.  
« Last Edit: February 27, 2017, 09:39:41 pm by RAW »
Windows 7 Pro (x64 Sp1) & Windows XP Pro (x86 Sp3).

 

TinyPortal © 2005-2018