Jump to content
dkprojektai

Memory leak in thread

Recommended Posts

Hello I have memory leaks in thread. Need help to fix them:

1.

          NewBitmap:= TBitmap.Create;
          NewBitmap.Canvas.Lock;
          NewBitmap.PixelFormat:= pf24bit;
          NewBitmap_first.Canvas.Lock;
          Try
            NewBitmap.Width:= StrToInt(Detector_scan_right) - StrToInt(Detector_scan_left); 
            NewBitmap.Height:= StrToInt(Detector_scan_bottom) - StrToInt(Detector_scan_top);
            NewBitmap.Canvas.CopyRect(NewBitmap.Canvas.ClipRect, NewBitmap_first.Canvas, Rect( <<<<< memory leak
            StrToInt(Detector_scan_left),
            StrToInt(Detector_scan_top),
            StrToInt(Detector_scan_right),
            StrToInt(Detector_scan_bottom)
            ));
          Finally
            NewBitmap.Canvas.Unlock;
            NewBitmap_first.Canvas.Unlock;
          End;

2.

Tekst_string:= StringReplace(Tekst_string, 'data', '', [rfReplaceAll, rfIgnoreCase]);

 

Thanks in advance. 

Delphi 10.2

Share this post


Link to post

Are you ever Free()'ing the TBitmap that you Create()?  The code above does not show that.  If you are not, then not only is the TBitmap being leaked, but all of the resources associated with the TBitmap.Canvas (its Brush, Font, and Pen) are leaked as well.  And in the code you showed, it is possible that those resources are not being allocated until the call to Canvas.CopyRect(), which is why you would think CopyRect() is the source of the leak.

Edited by Remy Lebeau

Share this post


Link to post
3 minutes ago, dkprojektai said:

I do it later.

Well, how do you expect people to help you when you don't show everything you are doing?

 

How do you know the resources are even being leaked at all?  Do you have a leak report from somewhere?

  • Like 1

Share this post


Link to post

I use Deleaker:

 

Program.exe!@System@@GetMem$qqri Line 4738 004075b0
Program.exe!@System@@NewUnicodeString$qqri Line 24650 0040c632
Program.exe!@Vcl@Graphics@TFont@GetHandle Line 2600 + 0xaadfa bytes 0058a6ca
Program.exe!@Vcl@Graphics@TCanvas@CreateFont Line 4230 + 0xacbea bytes 0058c4ba
Program.exe!@Unit1@TWorkerThread@Execute Line 10849 + 0xec3928 bytes 013a31f8
Program.exe!@Madexcept@HookedTThreadExecute$qqrpvt1 + 0x9c9ff bytes 004b0dab
Program.exe!@System@Classes@ThreadProc$qqrxp22System@Classes@TThread Line 14945 + 0x60395 bytes 0053fc65
Program.exe!@System@ThreadWrapper$qqspv Line 24423 0040c580
Program.exe!@Madexcept@CallThreadProcSafe$qqspvt1 + 0x9c8e5 bytes 004b0c91
Program.exe!@Madexcept@ThreadExceptFrame$qqsp21Madexcept@TThreadInfo + 0x9c94a bytes 004b0cf6
KERNEL32.DLL!BaseThreadInitThunk + 0x17 bytes 776e0417
ntdll.dll!RtlGetAppContainerNamedObjectPath + 0xeb bytes 7781662b
ntdll.dll!RtlGetAppContainerNamedObjectPath + 0xb8 bytes 778165f8
00000000 00000000

 

Share this post


Link to post

I see you're using MadExcept. Are you aware that it has built in leak detection?

 

I don't know deleaker but it might be that it can't track cross thread allocations/deallocations. I know some leak detection tools has problems with that.

Share this post


Link to post

Probably you'll need to show an complete program, obviously cut down to minimal form, if you want somebody to dig deeper. 

Share this post


Link to post
21 hours ago, dkprojektai said:

I use Deleaker:

 


Program.exe!@System@@GetMem$qqri Line 4738 004075b0
Program.exe!@System@@NewUnicodeString$qqri Line 24650 0040c632
Program.exe!@Vcl@Graphics@TFont@GetHandle Line 2600 + 0xaadfa bytes 0058a6ca
Program.exe!@Vcl@Graphics@TCanvas@CreateFont Line 4230 + 0xacbea bytes 0058c4ba
Program.exe!@Unit1@TWorkerThread@Execute Line 10849 + 0xec3928 bytes 013a31f8

 

That leak report is suggesting that a UnicodeString allocated when the TCanvas.Font property creates its HFONT handle is being leaked.  Why, who knows.  The only UnicodeString I see allocated in TFont.GetHandle() is from a call to System.UTF8ToString(), and the compiler should be cleaning up that UnicodeString automatically when TFont.GetHandle() exits.

 

That being said, do note that TBitmap and TCanvas ARE NOT THREAD SAFE.  One thing I notice in your code is that you are unlocking the TBitmap canvases after drawing, but you said that the TBitmap objects are being "freed later".  As soon as you unlock the canvases, the main UI thread is free to swoop in anytime and free the GDI resources behind the TBitmap objects' backs.  That very well could cause race conditions that lead to problems.  You have to keep the canvases locked for as long as you are using the TBitmap objects in a thread.  Otherwise, don't use TBitmap in a thread at all, use straight Win32 API calls instead.

  • Like 1

Share this post


Link to post
9 minutes ago, Remy Lebeau said:

Otherwise, don't use TBitmap in a thread at all, use straight Win32 API calls instead.

Or a pure Pascal library like graphics32

  • Like 1

Share this post


Link to post

I'll try to do Lock and UnLock everywhere where I will use bitmap before freeing it. 

 

 straight Win32 API calls - can I get any example?

 

I would like escape using Pascal library like graphics32 because then I will have to do many conversations. And this will impact to speed.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×