kyuzumaki Posted March 22, 2013 Share Posted March 22, 2013 (edited) Hi Guys, I've been tearing my hair out over this one. Cant figure out where the leak is. When I run my script it will constantly increase in memory usage until it eventually crashes. When I watch the memory usage of autoit in the task manager there is no increase in usage but the overall usage drops as soon as i close my script. Most of the code is very simple and by commenting out a single line I can stop the leak.. sadly this lines very important. Heres the function i'm running which seems to be the problem. Its a modified version of a _tesseract.au3 function which simply captures an area of a window to a file and I've added code to rotate this image by 90 degrees before its saved. EDIT: The memory usage increases quite rapidly about 12MB/min, the function is being called repeatedly in quick succession. expandcollapse popupFunc CaptureToTIFF($win_title = "", $win_text = "", $ctrl_id = "", $sOutImage = "", $scale = 1, $left_indent = 0, $top_indent = 0, $right_indent = 0, $bottom_indent = 0) Local $hWnd, $hwnd2, $hDC, $hBMP, $hImage1, $hGraphic, $CLSID, $tParams, $pParams, $tData, $i = 0, $hImage2, $pos[4] Local $Ext = StringUpper(StringMid($sOutImage, StringInStr($sOutImage, ".", 0, -1) + 1)) Local $giTIFColorDepth = 24 Local $giTIFCompression = $GDIP_EVTCOMPRESSIONNONE ; If capturing a control if StringCompare($ctrl_id, "") <> 0 Then $hwnd2 = ControlGetHandle($win_title, $win_text, $ctrl_id) $pos = ControlGetPos($win_title, $win_text, $ctrl_id) Else ; If capturing a window if StringCompare($win_title, "") <> 0 Then $hwnd2 = WinGetHandle($win_title, $win_text) $pos = WinGetPos($win_title, $win_text) Else ; If capturing the desktop $hwnd2 = "" $pos[0] = 0 $pos[1] = 0 $pos[2] = @DesktopWidth $pos[3] = @DesktopHeight EndIf EndIf ; Capture an image of the window / control if IsHWnd($hwnd2) Then WinActivate($win_title, $win_text) $size=WinGetClientSize($win_title,$win_text) $hBitmap2 = _ScreenCapture_CaptureWnd("", $hwnd2, 0, 0, -1, -1, False) Else $hBitmap2 = _ScreenCapture_Capture("", $size[0], 0, 0, $size[1], False) EndIf ;commented out and moved to start of code for debug _GDIPlus_Startup () $hImage2 = _GDIPlus_BitmapCreateFromHBITMAP ($hBitmap2) $hWnd = _WinAPI_GetDesktopWindow() $hDC = _WinAPI_GetDC($hWnd) $hBMP = _WinAPI_CreateCompatibleBitmap($hDC, ($pos[2] * $scale) - ($right_indent * $scale), ($pos[3] * $scale) - ($bottom_indent * $scale)) _WinAPI_ReleaseDC($hWnd, $hDC) $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP ($hBMP) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1) _GDIPLus_GraphicsDrawImageRect($hGraphic, $hImage2, 0 - ($left_indent * $scale), 0 - ($top_indent * $scale), ($pos[2] * $scale) + $left_indent, ($pos[3] * $scale) + $top_indent) ;removed tiff parameters settings for debug ; Save TIFF and cleanup $hImage3 = _GDIPlus_BitmapCreateFromGraphics(_GDIPlus_ImageGetHeight($hImage1), _GDIPlus_ImageGetWidth($hImage1), $hGraphic) $hGraphic3 = _GDIPlus_ImageGetGraphicsContext($hImage3) $matrix = _GDIPlus_MatrixCreate() _GDIPlus_MatrixRotate($matrix, -90) _GDIPlus_GraphicsSetTransform($hGraphic3, $matrix) _GDIPlus_GraphicsDrawImage($hGraphic3, $hImage1, -_GDIPlus_ImageGetWidth($hImage1), 0) _GDIPlus_ImageSaveToFile($hImage3, $sOutImage);, $CLSID, $pParams) ;replaced the below function call with code above for rotation to prevent nested starting of gdi plus ;rotate_image($sOutImage) _GDIPlus_MatrixDispose($matrix) _GDIPlus_ImageDispose($hImage1) _GDIPlus_ImageDispose($hImage2) _GDIPlus_ImageDispose($hImage3) _GDIPlus_GraphicsDispose ($hGraphic) _GDIPlus_GraphicsDispose ($hGraphic3) _WinAPI_DeleteObject($hBMP) sleep(100) ;_GDIPlus_Shutdown() EndFunc Edited March 23, 2013 by kyuzumaki Link to comment Share on other sites More sharing options...
kyuzumaki Posted March 22, 2013 Author Share Posted March 22, 2013 After posting I decided that I didn't trust _GDIPlus_Shutdown() or _GDIPlus_Startup() so I removed them entirely and executed them once at the beginning and end of the script. But no luck still getting the same issue out of ideas now.... Link to comment Share on other sites More sharing options...
Danp2 Posted March 23, 2013 Share Posted March 23, 2013 I have experienced a similar memory leak while using GDIPlus. Here's my routine, which combines two images and saves them to a new file: expandcollapse popupFunc CombineImages() $MergedImageBackgroundColor = 0x00000000 ;Specify 00 on first "digits" for transparent color (.png only !), all other values (......) will be ignored. ; Load image 1 $hImage1 = _GDIPlus_ImageLoadFromFile($frontDir & $sFront) $iX1 = _GDIPlus_ImageGetWidth($hImage1) If $iX1 = 4294967295 Then $iX1 = 0 $iY1 = _GDIPlus_ImageGetHeight($hImage1) ; Load image 2 $hImage2 = _GDIPlus_ImageLoadFromFile($backDir & $sBack) $iX2 = _GDIPlus_ImageGetWidth($hImage2) If $iX1 = 4294967295 Then $iX1 = 0 $iY2 = _GDIPlus_ImageGetHeight($hImage2) ; Name of destination image $sDest = $combinedDir & StringReplace($sFront, "front_", "") $height = $iY1 + $iY2 $width = _Max($iX1, $iX2) ; Initialise the Drawing windows/composite image... $hGui = GUICreate("GDIPlus Example", $width, $height) ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui) ;Draw to this graphics, $hGraphicGUI, to display on GUI $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($width, $height, $hGraphicGUI) ; $hBMPBuff is a bitmap in memory $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff) ; Draw to this graphics, $hGraphic, being the graphics of $hBMPBuff ;Fill the Graphic Background (0x00000000 for transparent background in .png files) _GDIPlus_GraphicsClear($hGraphic, $MergedImageBackgroundColor) ;Put the previously opened images together on the same Graphic and closing them _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hImage1, 0, 0, $iX1, $iY1, 0, 0, $iX1, $iY1) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hImage2, 0, 0, $iX2, $iY2, 0, $iY1, $iX2, $iY2) _GDIPlus_ImageDispose($hImage1) _GDIPlus_ImageDispose($hImage2) ConsoleWrite($sDest & @CRLF) ; Save composite image (need that previously opened images have been closed if self-merging a file) If Not _GDIPlus_ImageSaveToFile($hBMPBuff, $sDest) Then ConsoleWrite("Error - " & $sDest & @CRLF) EndIf _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose($hGraphicGUI) _WinAPI_DeleteObject($hBMPBuff) GUIDelete ($hGui) EndFunc Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
kyuzumaki Posted March 23, 2013 Author Share Posted March 23, 2013 (edited) Does your function produce a leak? Or did you solve it somehow? Its really frustrating because the program can only do about 2000 iterations before crashing i need it to do alot more Is there an alternative to GDIPlus that will capture and rotate an image? I dont mind if its a bit slower as long as theres no memory leak Edited March 23, 2013 by kyuzumaki Link to comment Share on other sites More sharing options...
FireFox Posted March 23, 2013 Share Posted March 23, 2013 @kyuzumaki You forgot to release this ressource : _GDIPlus_BitmapDispose($hBitmap2) Br, FireFox. Link to comment Share on other sites More sharing options...
FireFox Posted March 23, 2013 Share Posted March 23, 2013 After posting I decided that I didn't trust _GDIPlus_Shutdown() or _GDIPlus_Startup()Furthermore, it's clearly written in the help file that _GDIPlus_Shutdown does not release the ressources used with the GDIPlus functions :You must dispose of all of your GDI+ objects before you call _GDIPlus_Shutdown Link to comment Share on other sites More sharing options...
kyuzumaki Posted March 23, 2013 Author Share Posted March 23, 2013 (edited) Thanks FireFox that! I got a tool that tracks the GDI plus usage and it showed loads of bitmaps thats clearly the problem.For some reason when I call the bitmap dispose method it crashes? Thoughts?EDIT: Solved the screen capture is a HBitmap so you need to use the below line to dispose of it_WinAPI_DeleteObject($hBitmap2)Thanks! Edited March 23, 2013 by kyuzumaki Link to comment Share on other sites More sharing options...
FireFox Posted March 23, 2013 Share Posted March 23, 2013 EDIT: Solved the screen capture is a HBitmapYes right I was misled by the var name. Link to comment Share on other sites More sharing options...
Danp2 Posted March 23, 2013 Share Posted March 23, 2013 Does your function produce a leak? Or did you solve it somehow? Its really frustrating because the program can only do about 2000 iterations before crashing i need it to do alot moreI haven't run this routine in a while, but I believe I was experiencing the same issue where it crashed after a limited number of iterations. Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now