Thread Tools Display Modes
08/18/15, 04:23 AM   #1
QuadroTony
Banned
AddOn Author - Click to view addons
Join Date: Apr 2014
Posts: 828
Help to track down memory leak

it connected with Shissu guild tools addon
i think we together can help to fix it faster
afaik Shissu tried to fix it in last updates but without luck

www.youtube.com/watch?v=2cANGJ1RfoQ


P.S. also i kicked for spamming when promoting/demoting too fast, like 2 per second
its weird because its not fast enough to be kicked

probably because of SGT too

Last edited by QuadroTony : 08/18/15 at 04:36 AM.
  Reply With Quote
08/18/15, 05:49 AM   #2
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Looked at the code, and found two points that might be a start to identifying why it happens.

1. SGT alters the scroll list in a very evil and inefficient way.

Hooking ZO_ScrollList_UpdateScroll and other generic functions is not nice. All hooks referecing SGT_Roster.ColumnUpdateHandler should be removed and replaced with just this one:

Lua Code:
  1. local orgSetupGuildMember = GUILD_ROSTER_MANAGER.SetupGuildMember
  2. function GUILD_ROSTER_MANAGER:SetupGuildMember(control, data)
  3.     orgSetupGuildMember(self, control, data)
  4.     SGT_Roster.NewColumnAddRow(control, data)
  5.     -- it currently doesn't use the second arg, but could, for convenience
  6. end

It could be further optimized by moving sub-control creation to row-control creation callback, but that'd be more work for a negligible effect, so not really that necessary.


2. SGT_Roster.NewColumnAddRow could use a little optimization.

In my opinion it shouldn't construct tooltip strings at all. Their construction should be deferred to the moment right before tooltip display, i.e. OnMouseEnter.

Btw, I'm just guessing, but perhaps the tooltip creation is what eats the memory. There's a loop over MemberChars, with character names being appended to the tooltip one by one, each after the first doing 2 string concats.

ShissuGT.Lib.GetCharInfoIcon does 0 to 3 concats. It should be changed to string.format("|t28:28:%s|t%s", icon, text) -- that will remove the 2 intermediate string allocations.

SGT_Roster.NewCharName consequently does 1 to 7 concats. With fixed GetCharInfoIcon it will be 1 to 3.

So for 8 characters, there will be (1 to 7) + 7 * (3 to 9) concatenations. Due to all the above points combined, this happens every time you scroll the list for all people you currently see (roughly 20). That's 400-1200 string concats. I don't know when Lua discards unused strings, I hope it does at some point, but this looks like it's allocating too many too fast.

Refactored tooltip construction
Lua Code:
  1. local function buildTooltip(MemberChars)
  2.     local lines = {}
  3.     for charName, charInfo in pairs(MemberChars) do
  4.         lines[#lines + 1] = SGT_Roster.NewCharName(charName, charInfo)
  5.     end
  6.     table.sort(lines) -- making the order consistent can't hurt ;)
  7.     return table.concat(lines, "\n")
  8. end
  9.  
  10. charNameControl.tooltip = nil
  11.  
  12. charNameControl:SetHandler("OnMouseEnter", function (self)
  13.     if self.tooltip == nil then
  14.         local MemberChars = SGT_Roster.MemberChars[displayName]
  15.         if MemberChars then
  16.             self.tooltip = buildTooltip(MemberChars)
  17.         else
  18.             self.tooltip = false
  19.         end
  20.     end
  21.     if self.tooltip then
  22.         ZO_Tooltips_ShowTextTooltip(self, TOP, self.tooltip)
  23.     end
  24. end)
  25.  
  26. charNameControl:SetHandler("OnMouseEnter", function (self)
  27.     ZO_Tooltips_HideTextTooltip()
  28. end)

Last edited by merlight : 08/18/15 at 07:39 AM.
  Reply With Quote
08/18/15, 06:36 AM   #3
votan
 
votan's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 577
What about using enclosure variable charNameControl instead of self. Shouldn't "self" be the same reference as "charNameControl" and does it matter at all?
I'm still confused about this enclosure magic and it's implicit memory usage.

/edit: You understood me right at first time. I just was not sure, if its really matter or the enclosure will exist anyway, because it is a nested function.

Last edited by votan : 08/18/15 at 08:00 AM. Reason: answer to merlight's edit
  Reply With Quote
08/18/15, 07:39 AM   #4
merlight
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 671
Originally Posted by votan View Post
What about using enclosure variable charNameControl instead of self. Shouldn't "self" be the same reference as "charNameControl" and does it matter at all?
I'm still confused about this enclosure magic and it's implicit memory usage.
You're right, I should've used "self" in the handler; was copying the pieces from outer scope and forgot to replace them. Code edited.

Edit: oh you meant the other way around? I suppose local variable access (function arguments are local variables, too) is simpler than closure variable access. Specifically, using self, charNameControl doesn't need to be in the closure at all.

Last edited by merlight : 08/18/15 at 07:45 AM.
  Reply With Quote
08/18/15, 04:43 PM   #5
circonian
AddOn Author - Click to view addons
Join Date: May 2014
Posts: 613
I agree with what merlight said. The biggest problem looks like those functions, the prehook on ZO_ScrollList_MouseEnter (fires no matter what scroll list your mouse enters), and mainly the prehook on ZO_ScrollList_UpdateScroll. Scrolling a single line caused that update preHook to fire 26 times. Which in turn loops through all 19 active controls for each of the 26 fires which means its processing all of that information for each line you scroll in the scrollList 19*26 = 494 times (minimum, thats not even counting mouseEnter fires as the list scrolls).

Last edited by circonian : 08/18/15 at 05:25 PM.
  Reply With Quote
08/21/15, 04:50 AM   #6
Shissu
AddOn Author - Click to view addons
Join Date: Jan 2015
Posts: 2
in a newer version the problem is solved....

i dont use then more the activecontrols, i change the roster direct - but first update 7 fix....
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » Help to track down memory leak


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off