[cc-ing Lou. We need to improve the documentation on the Debugger memory tools. I thought I had written something, but I can't seem to find it, and the current doc

http://www.openlaszlo.org/lps4/docs/developers/debugging.html#d0e121455

is confusing even to me. I've attached some additional info to the end of this message.]

On 2008-04-09, at 11:27 EDT, Gilad Parann-Nissany wrote:
Hi

We're trying to optimize our memory usage, not exactly find leaks but profile our memory. We are on OL 4.0.8.

So far we've used _LzDebug.whyAlive() to analyze an application; is there a different recommended way to analyze the memory allcoation of an OL app? or are we doing the right thing?

That's the best tool we have for fine-grained analysis. I also use the operating system's memory profile tools to see if my application is growing without bound, although this is a very 'noisy' measure, because all you can look at is the total memory of the browser. If you are _only_ running your application in the browser, it is quite likely that any fluctuation in memory usage is due to your application, but also note that most runtimes will only garbage collect when your application is idle. Sometimes minimizing the browser window will trigger a garbage collection.

Attached a screenshot of an example run. We need help to understand this output:

   • what are smoots?

An small (inside) joke:  http://en.wikipedia.org/wiki/Smoot

   • why do objects contain smoots?

Since the memory leak detector is running in the SWF or DHTML virtual machine, it has no way to actually measure the size of an object in bytes. It approximates the size of an object by counting the objects properties, and by assuming some reasonable defaults for built-in objects like numbers and strings. Smoots should be proportional to bytes, but they are not bytes.

• what are the numbers that start with a pound-sterling sign? in regular paranthesis like Array(4)? with "#" like in Array(4) #262

This is intended to represent the 'total weight' of the object. It is the sum of the object's smoots and the smoots of it's children and it's children's children, etc.

• how to interpret the names on the leftmost side such as global.spriteroot? the ones after the colon?

This is the shortest path from the root to the object, the most likely reason the object is still 'alive'. (There may be other links to the object, but the tool only records the shortest one.)

is there any way we can translate these into bytes of memory? we have measured total RAM used separately, but would like to know whether the result of whyAlive is a dependable measure of the breakdown of this memory...

As above, smoots should be proportional to total memory.

---

[Additional info]

As of 4.0.8, there are some fixes for the leak detection tools. The leak detector no longer gets fooled by getters in the runtime that return a new object each time you access a property. You no longer have to go through hoops to get the output of `Debug.whyAlive()` -- it prints out a useful summary again, and if you inspect the result, you get the full report. Each element in the leak report is also inspectable. Ex.:

lzx> Debug.markObjects()
Marking objects ...
lzx> DEBUG: 7 loops @ 1379 iterations, 1137.97 milliseconds
... done!
lzx> Debug.findNewObjects()
Finding new objects ...
lzx> DEBUG: 7 loops @ 1379 iterations, 1153.63 milliseconds
... done!
lzx> Debug.whyAlive()
82 smoots [4 objects @ ~21 smoots each]:
global.spriteroot.$m1.debugloader.loadmc1.reqobj: (£54) «Object#138| {_dbg_check: 54, _dbg_smoots...» global._componentmanager.service.upkeydel: (£20) «LzDelegate#141| «lz._componentmanager».d...»
global.LzKeys.downKeysArray: (£8) «Array(2)#144| [16, 68]»
.: (£0) «¿movieclip?»
«__LzLeaks(4)#136| 82 smoots [4 objects @ ~21 smoots each]»
lzx> Debug.inspect(82 smoots [4 objects @ ~21 smoots each])
«__LzLeaks(4)#136| 82 smoots [4 objects @ ~21 smoots each]» {
 constructor:         __LzLeaks
      length:         4
0: global.spriteroot. $m1.debugloader.loadmc1.reqobj: (£54) «Object#138| {_dbg_check: 54, _dbg_smoots...» 1: global._componentmanager.service.upkeydel: (£20) «LzDelegate#141| «lz._componentmanager».d...» 2: global.LzKeys.downKeysArray: (£8) «Array(2)#144| [16, 68]»
           3:         .: (£0) «¿movieclip?»
}«__LzLeaks(4)#136| 82 smoots [4 objects @ ~21 smoots each]»
lzx> Debug.inspect(«__LzLeak| global.LzKeys.downKeysArray: (...»)
«__LzLeak#151| global.LzKeys.downKeysArray: (£8) «Array(2)#144| [16, 68]»» {
 constructor:         __LzLeak
      leaked:         8
         obj:    (£8) [16, 68]
      parent:         #LzKeys
        path:         'global.LzKeys'
    property:         'downKeysArray'
}«__LzLeak#151| global.LzKeys.downKeysArray: (£8) «Array(2)#144| [16, 68]»»

This shows inspecting the memory report '__LzLeaks', which has four leaks reported, and then inspecting an individual leak report '__LzLeak', which has the amount 'leaked', the 'obj'ect that the report is about, the 'parent' of that object (the object that is referencing the reported object, the 'path' from the root to the parent, and the 'property' of the parent that contains the reported object.

Hope this is helpful.  Let me know if there are further questions.



Reply via email to