How to release the object from memory?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Drugoy
Posts: 48
Joined: 11 Jun 2016, 07:37
Contact:

How to release the object from memory?

Post by Drugoy » 05 Oct 2016, 09:57

How to release the memory occupied by an object, created this way?

Code: Select all

Gui, Add, ActiveX, vObj hwndObjHWND, about:<!doctype html><meta http-equiv="X-UA-Compatible" content="IE=Edge">
I've tried ObjRelease(&Obj). I've tried Obj := "", but nothing helps: the memory consumed by the script's process remains on a high level, it doesn't shrink much.
Maybe these commands work out correctly and release the object, but how to invoke memory shrink?
The only thing that actually works is Reloading the script.

p.s.: also I've noticed that executing

Code: Select all

Obj := ""	; or Obj := {}
ObjRelease(&Obj)
crashes ahk. I'd prefer an error instead.

Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: How to release the object from memory?

Post by Helgef » 05 Oct 2016, 10:19

Try

Code: Select all

obj.SetCapacity(0)
or

Code: Select all

VarSetCapcity(obj,0)

User avatar
Capn Odin
Posts: 1352
Joined: 23 Feb 2016, 19:45
Location: Denmark
Contact:

Re: How to release the object from memory?

Post by Capn Odin » 05 Oct 2016, 10:20

I don't think this is the correct approach, but maybe if you destroy the gui.
Please excuse my spelling I am dyslexic.

Drugoy
Posts: 48
Joined: 11 Jun 2016, 07:37
Contact:

Re: How to release the object from memory?

Post by Drugoy » 05 Oct 2016, 11:21

Capn Odin
Yeah, I did try Gui, Destroy and that doesn't help too.

Helgef
Using Obj.SetCapacity(0) results into Error: 0x80020006 - Unknown name. Specifically: SetCapacity.
And VarSetCapcity(obj,0) behaves like ObjRelease(&Obj) - the memory doesn't shrink the way I expect it to. Though it does shrink a little.

lexikos
Posts: 9665
Joined: 30 Sep 2013, 04:07
Contact:

Re: How to release the object from memory?

Post by lexikos » 06 Oct 2016, 04:07

Obj := "" is the correct and only way to release your reference to an object referred by Obj.

You cannot explicitly delete an object; you must allow it to be deleted automatically when its last reference is released. To delete the object before then would leave dangling pointers; pointers which the program believes point to valid objects but actually point to garbage. When someone tries to invoke that garbage, even just to release their reference, the result can be unpredictable (but is often a crash).
AutoHotkey uses a basic reference-counting mechanism to automatically free the resources used by an object when it is no longer referenced by the script. Script authors should not invoke this mechanism explicitly, except when dealing directly with unmanaged pointers to objects.
Source: Objects - Reference Counting
In this case, the object to which Obj refers is a ComObject. Not a "COM object" - a ComObject. This is a "wrapper" object which represents a COM object or value and adapts it to AutoHotkey's type system. Even when this ComObject is deleted, it does not (and cannot) delete the actual COM object. Firstly for the same reasons as above, and secondly because the program doesn't know how the object was allocated.

Furthermore, deleting the COM object will not restore the process memory usage to how it was before you created the object. That one COM object was not single-handedly responsible for the increase in memory usage. That object was implemented by a library (likely ieframe.dll in your case), and it used other objects implemented by other libraries (such as mshtml.dll when you load some HTML). Those libraries typically will not be unloaded before your process exits. After all, the program might want to create more such objects.

Why are you even concerned about memory usage? Is your system running out of memory? How high is "a high level"?
Drugoy wrote:I'd prefer an error instead.
AutoHotkey can't reasonably be designed to detect the particular mistake that you made. The best it could do is catch whatever generic SEH exception occurs and report that something went wrong. However, Windows already does that.

Drugoy
Posts: 48
Joined: 11 Jun 2016, 07:37
Contact:

Re: How to release the object from memory?

Post by Drugoy » 06 Oct 2016, 05:03

Thank you for your detailed answer, lexikos.
I got the part about how I don't need to do anything other than releasing my reference to the object with simple Obj := "".
Probably, this does indeed result into the unallocation of the ahk's ComObject wrapper and maybe even in unallocation of the referenced COM object in the system and the amount of consumed memory remains on high level only because the dependent libraries that got loaded - don't get unallocated as well.
I've tried DllCalling "FreeLibrary" to free up ieframe.dll and mshtml.dll - and that does in deed free up extra 30MB.

As for memory consumption concerns - of course that's not critical for my system where I have lots of available RAM, yet still I'd like to find a way to clean things up, because:
1. Starting ahk script: ~8MB.
2. Doing

Code: Select all

Gui, Add, ActiveX, vObj hwndObjHWND, about:<!doctype html><meta http-equiv="X-UA-Compatible" content="IE=Edge">
Obj.Document.Open()
Obj.Document.Write("<html><body><a href=""http://imdb.com/"">imdb</a></html>")
Obj.Document.Close()
Gui, show
~29MB.
3. Clicking on the link: ~137-140MB.
4. Calling

Code: Select all

Gui, Destroy
Obj := ""
~96-115MB.

The end result is 12-14 times more than the amount of allocated memory at script's start.
Plus, as you can see just loading a simple html takes a pretty okay amount of memory, it's loading sites is what adds up most.
Maybe closing the site, destroying the gui and releasing the reference to the object still leaves some cache behind, maybe you know what I should do to reduce the memory consumption in the above mentioned scenario?

Drugoy
Posts: 48
Joined: 11 Jun 2016, 07:37
Contact:

Re: How to release the object from memory?

Post by Drugoy » 13 Oct 2016, 09:21

So does anyone know why the memory consumption stays 12-14 times more after releasing the object compared to script's startup?

User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: How to release the object from memory?

Post by jNizM » 14 Oct 2016, 00:47

Can you give a working example?
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile

Stuff n Things

Re: How to release the object from memory?

Post by Stuff n Things » 14 Oct 2016, 09:01

I just wanted to chime in with Drugoy and say that I too have noticed a high amount of memory being taken up by svchost.exe when creating / destroying a significant number of COM object wrappers.

As a work around, I use:

Code: Select all

HttpObj := ComObjCreate("WinHttp.WinHttpRequest.5.1")
HttpObj.Open("GET", "https://www.google.com")
HttpObj.Send()
HTML := HttpObj.ResponseText
Which, even after several thousand instances, doesn't appear to take up a significant amount of memory.

Drugoy
Posts: 48
Joined: 11 Jun 2016, 07:37
Contact:

Re: How to release the object from memory?

Post by Drugoy » 16 Oct 2016, 15:29

jNizM, I already gave a working example. Just add w800 h600 to the first command's 3rd argument so that the window would be displayed ~normally.

Drugoy
Posts: 48
Joined: 11 Jun 2016, 07:37
Contact:

Re: How to release the object from memory?

Post by Drugoy » 16 Oct 2016, 15:57

Stuff n Things, my issue is not about memory consumed by other processes, but about the memory consumed by the ahk's process itself.
Also, your code doesn't show the site's contents in a GUI rendered as a page, unlike it does happen in my script.

Drugoy
Posts: 48
Joined: 11 Jun 2016, 07:37
Contact:

Re: How to release the object from memory?

Post by Drugoy » 21 Oct 2016, 12:27

It's a pity this didn't get resolved.

User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: How to release the object from memory?

Post by Masonjar13 » 22 Oct 2016, 04:37

While the gui exists, the following libraries are loaded:
msvcrt.dll
ntdll.dll
mshtml.dll
WINMM.dll
combase.dll

After destroying it and releasing the object, you're left with all of those except mshtml.dll. By what you said about using FreeLibrary(), I assume you can get the handles for these? I'm not sure how to find them myself, never had the need.

Note: I tested this on W8.1. You can use ProcExp (Process Explorer by SysInternals) to see loaded libraries (view current threads on the process).

Edit: Correction, you should be left with WINMM.dll, ntdll.dll, and combase.dll.
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build

Janusz
Posts: 89
Joined: 18 Dec 2020, 17:47

Re: How to release the object from memory?

Post by Janusz » 09 Jan 2023, 09:02

I have randomly read this post about memory allocations by using COM objects. The problem is, that Autohotkey script is user of those COM objects. So it is impossible to clean memory allocations caused by other COM libraryes. To be honest, I do not know about other opensource and free programming language which manage memory so professionally like Autohotkey does. It is really necessary to be aware, that Autohotkey internal commands which do not call external object libraryes are doing its best to allocate RAm as much professionally as possible. Even if you would use Assembly language or C, your code which would call external object would create process, which allocate memory according to dlls which are used by com object calls.
Lexikos is really elite programmer and his code must be also secure to prevent us rather amateour users who are users of high programming language, Autohotkey to protect us against severe system crash. Windows kernel protect users also as good as possible. I have invented my own concept, that Windows kernel is friendly authority which protect users against unstable applications and The device drivers.
So if somebody want to make very low memory allocations, somebody would had to develop his own .dll in C or C++ and unfortunately, even Milliard US $ company can not always create .dll which will allocate 20 MB for example
Autohotkey for its own internal command support special directive where user can specify, when automatic routines will do its best to clean memory.
I will give you a simple example.
Try to call bass.dll.
Programmer can not free its memory allocations when some of its procedures or functions are working.
Windows can even use pagefile.sys and build in CPU instructions to allocate virtual memory if necessary.
Programmer can even use Kernel32.dll calls to allocate virtual memory pages. But it is advanced elite programmers work.
If you have freed memory by using some other dll, may be, that it is safe for your COM object library, but it could cause issues when using other library.

Post Reply

Return to “Ask for Help (v1)”