Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


When to destroy objects?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
jgoemat
Master Cheater
Reputation: 22

Joined: 25 Sep 2011
Posts: 252

PostPosted: Mon Aug 25, 2014 2:45 am    Post subject: When to destroy objects? Reply with quote

I'm working through some LUA stuff and updating the wiki and was wondering if and when to destroy objects and what needs to be destroyed.

For instance if I use "createMemScan()" and then "createFoundList()" when the scan is compete, do I need to destroy both objects to free the memory?

If I use getCurrentMemscan() to access the main window scan, should I avoid destroying that? If I call createFoundList() on it should I destroy that?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25288
Location: The netherlands

PostPosted: Mon Aug 25, 2014 4:46 am    Post subject: Reply with quote

Things you create should be destroyed yes. So both the foundlist and memscan object

getCurrentMemscan() doesn't create it, so don't destroy this
If you attach a foundlist to that unspecified behaviour will occur. Just get the current foundlist of that memscan object.(or at least restore it when done)

One thing to note are objects on a form. If you destroy a form the objects on it will be destroyed as well, so do nt free those after having freed the form

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
fingersmith
Newbie cheater
Reputation: 0

Joined: 05 Apr 2016
Posts: 17

PostPosted: Fri Jul 08, 2016 4:09 am    Post subject: Reply with quote

I am under the impression that LUA automatically perform garbage collection...aka no need to destroy object explicitly.

FS
Back to top
View user's profile Send private message AIM Address
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25288
Location: The netherlands

PostPosted: Fri Jul 08, 2016 5:15 am    Post subject: Reply with quote

it garbage collects lua things yes, but the objects you create with create* functions are just wrappers for native code objects. Those do need to get destroyed manually
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
panraven
Grandmaster Cheater
Reputation: 55

Joined: 01 Oct 2008
Posts: 942

PostPosted: Fri Jul 08, 2016 5:38 am    Post subject: Reply with quote

In Lua 5.3 so ce 6.5, there is a metamethod __gc to handle ce object with Lua's garbage collecting.
https://www.lua.org/manual/5.3/manual.html#2.5.1

_________________
- Retarded.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25288
Location: The netherlands

PostPosted: Fri Jul 08, 2016 5:57 am    Post subject: Reply with quote

yeah, but keeping track of all lua variables that reference a specific object is quite taxing.

e.g: you can get an reference to a form, a button on the form, and edit field on a form.

when you close the form, and it's close action is caFree, the form, button and edit field need to be dereferenced as well, and the garbage collector needs to be told to NOT free them

there is some testing implemented in ce with regard to garbage collecting
e.g this script:
Code:

for i=1,10 do
  f=createForm()
  m=getmetatable(f)
  m.__autodestroy=true
end
collectgarbage()


will create 10 forms of which 9 will be destroyed when f gets garbage collected

of course, if you close the last form, nil f, and then the garbage collector runs, lua will crash, as it tries to nil the form.

so in the ondestroy of the form, you'd have to add the code:
Code:

getmetatable(f).__autodestroy=false



and not to mention that the sender and f in the ondestroy object of the form are not the same object. And if I where to keep references to created objects inside objects themself they would never get destroyed by the garbage collector causing a lua sided memory leak...

so yeah, just destroy it manually

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
panraven
Grandmaster Cheater
Reputation: 55

Joined: 01 Oct 2008
Posts: 942

PostPosted: Fri Jul 08, 2016 6:34 am    Post subject: Reply with quote

Quote:
...
so yeah, just destroy it manually

Yes, can't think of a practical use case.

Anyway, here a testing of __gc.

Code:
function testgc(i)
  i = i and tostring(i) or '?'
  local fm = createForm()
  fm.OnClose = function(me)me.Destroy() fm = nil return caFree end
  fm.Caption = i
--  local m=getmetatable(fm)
--  m.__autodestroy=true
  --  test for which first? gchandler.__gc or m.__autodestroy? seems __gc ~

  local gchandler = setmetatable({},{__gc=function() -- fm will be REVIVE from out of scope?
    local cn =fm and fm.Destroy and fm.ClassName -- test for destroyed ce object, reliazble?
    if type(cn)=='string' and cn:len()>3 and not cn:find('[^_%w]') then
      fm.Destroy()
      print('form '..i..' destroyed')
    else
      print('form '..i..' already destroyed, may be by manual close form')
    end
  end})

 -- official manual said __gc cannot be added to a metatable to be functional, it has to be set by setmetatable, so __gc cannot be 'attach' to fm.

 -- gchandler, not fm, will be MARK to be gc when go out of scope,
 -- gchandler.__gc will be called in next gc cycle

end

for i=1,10 do
  testgc(i)
end

local gctrigger,cnt = createTimer(),4
gctrigger.Inteval = 1000
gctrigger.OnTimer = function(me)
  cnt = cnt - 1
  if cnt>0 then
    print(cnt..' sec to manual gc')
  else
    me.Destroy()
    collectgarbage()
  end
end



ADDED:
the __autodestroy codes is comment out, since it may cause the 'manual close form' problem as Dark Byte said.

ADDED:
oops, 'test for destroyed ce object' is not reliazble, it still cause access violation some time.
-- added:
set fm to nil in OnClose seems prevent this happened.

_________________
- Retarded.
Back to top
View user's profile Send private message
akumakuja28
Master Cheater
Reputation: 16

Joined: 28 Jun 2015
Posts: 432

PostPosted: Thu Jul 14, 2016 11:52 am    Post subject: Reply with quote

I would recommend just using collectgarbage() but it is fucking notorious for breaking things. Even if using destroy().

Things I have often experienced from garbage collecting are.
-- Breaking of the address list
Injection templates cause access violations
Unable to edit names or values on the address list.
Loss of the file menu
Random access violations when searching.
And plenty of other things.

The memory leak with LUA is ridiculous. Your best bet is to build your forms and never destroy just use hide().

Easy code for hiding a form
If Form~= nil
then
Form.Visible = true
Else
Whatever your formcreate() function is.
End

function CloseForm()
Form.Visible = false
End


Form.OnClose = CloseForm


Dont use an embedded function like

Form.OnClose = function()
Form.Visible = false
End

As these tend to break them selfs also.








Running that arguement works great to reduce the memory impact of
Create and Destroy(). As eventually you WILL create an access violation with this practice. At some time CE will eventually write over a section
Of code it needs for something else. Now while this experience maybe
Anecdotal it is just my experience from writing a CE extension to Manage games and cheat tables. And in this I have defined well over 400 things in LUA.

I know this sounds rant like. But honestly whenever you create something in CE lua environment try your hardest to reuse that asset vs recreation. Which brings me to another point stay away from any "local" variable as these things are notorious for memory leaks.

_________________
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 218

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Fri Jul 15, 2016 1:24 pm    Post subject: Reply with quote

akumakuja28 wrote:
Things I have often experienced from garbage collecting are.
-- Breaking of the address list
Injection templates cause access violations
Unable to edit names or values on the address list.
Loss of the file menu
Random access violations when searching.
And plenty of other things.

Any proof? Post CT file (one or more).


akumakuja28 wrote:
Dont use an embedded function like

Form.OnClose = function()
Form.Visible = false
End

As these tend to break them selfs also.

What? Can you post a code so I can try to reproduce this issue?

_________________
Back to top
View user's profile Send private message MSN Messenger
akumakuja28
Master Cheater
Reputation: 16

Joined: 28 Jun 2015
Posts: 432

PostPosted: Fri Jul 15, 2016 4:33 pm    Post subject: Reply with quote

mgr.inz.Player wrote:
akumakuja28 wrote:
Things I have often experienced from garbage collecting are.
-- Breaking of the address list
Injection templates cause access violations
Unable to edit names or values on the address list.
Loss of the file menu
Random access violations when searching.
And plenty of other things.

Any proof? Post CT file (one or more).



Quote:
Now while this experience maybe
Anecdotal it is just my experience from writing a CE extension to Manage games and cheat tables. And in this I have defined well over 400 things in LUA.





Just my experience if I could recreate it on demand i would post the LUA code. I can give a more accurate description of what leads to the random "Access Violation".


It Mostly Occurs with code Below:

Code:

print(collectgarbage("count")/(1024).."   MB")
collectgarbage()
print(collectgarbage("count")/(1024).."   MB")


Executed on timer or executed in rapid manual fashion.

It also seems to break easier when A large number of LUA Defines are in Memory.
Although its Randomness I cant seem to track down.
eg. I will have One form loaded from a dofile(), run the garbagecollect() and the addressList goes "Access Violation". Other times No Load of dofile().
And timer kicks in to do garbagecollect() and breaks something.

Still I can go a couple days with a Massive amount of LUA defines, Forms, Timers, stringlists and Nothing breaks at all and CE will Run at about 100mb in the Memory. Other Times I will Run into an error almost immediately.


If you want mgr I can send over what im working on. And you can see the Issue yourself.



It really is Random. :/

_________________
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 218

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Fri Jul 15, 2016 4:40 pm    Post subject: Reply with quote

OK, send it.

PS: do not attach any file to PM. Just paste a link to googledrive, onedrive or whatever you are using.

_________________
Back to top
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites