dkprojektai 1 Posted September 30, 2019 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
Remy Lebeau 1436 Posted September 30, 2019 (edited) 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 September 30, 2019 by Remy Lebeau Share this post Link to post
Remy Lebeau 1436 Posted September 30, 2019 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? 1 Share this post Link to post
dkprojektai 1 Posted September 30, 2019 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
Anders Melander 1815 Posted October 1, 2019 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
David Heffernan 2353 Posted October 1, 2019 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
Remy Lebeau 1436 Posted October 1, 2019 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. 1 Share this post Link to post
David Heffernan 2353 Posted October 1, 2019 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 1 Share this post Link to post
dkprojektai 1 Posted October 1, 2019 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
David Heffernan 2353 Posted October 1, 2019 graphics32 is generally faster than gdi I believe 1 Share this post Link to post