Thank you for the useful answer.
Another Q along these lines. We also want to measure the breakdown of memory
when we initialize .
This gives us the problem: when should we call
1.
markObjects()
2.
findNewObjects()
3.
whyAlive()
Thanks
Gilad
Gilad Parann-Nissany
----- Original Message -----
From: "P T Withington" <[EMAIL PROTECTED]>
To: "Gilad Parann-Nissany" <[EMAIL PROTECTED]>
Cc: "laszlo-user" <[email protected]>, "Ammar Tamazi" <[EMAIL
PROTECTED]>, "Elias Khalil" <[EMAIL PROTECTED]>, "Lou Iorio" <[EMAIL
PROTECTED]>
Sent: Sunday, April 13, 2008 4:42:27 PM (GMT+0200) Auto-Detected
Subject: Re: [Laszlo-user] Understanding memory analysis when using
_LzDebug.whyAlive()
It is my intent that a smoot be roughly proportional to the storage a
'reference' would take.
All the program can do is count properties of objects. We know
objects are implemented as hash tables, but we don't know the
algorithm. We believe strings are stored separately, but that other
primitive types are stored directly. The current algorithm is to
count 2 smoots for each property of an object and add the length of a
string divided by 4 for each property that is a string.
As I said, it is only a very rough measure of size. It can be used to
judge relative sizes of objects, but you should not be trying to use
it to measure the memory footprint of an application.
On 2008-04-13, at 09:18 EDT, Gilad Parann-Nissany wrote:
>
>
> Hi
>
> Thanks for the answer. A further clarification: is a smoot roughly
> proportional to one byte or can the proportion be - say - 16 ?
>
> Thanks!
>
> Gilad
>
>
>
> Gilad Parann-Nissany
>
> ----- Original Message -----
> From: "P T Withington" <[EMAIL PROTECTED]>
> To: "Gilad Parann-Nissany" <[EMAIL PROTECTED]>, "Lou
> Iorio" <[EMAIL PROTECTED]>
> Cc: "laszlo-user" <[email protected]>, "Ammar Tamazi" <[EMAIL
> PROTECTED]
> >, "Elias Khalil" <[EMAIL PROTECTED]>
> Sent: Wednesday, April 9, 2008 8:51:26 PM (GMT+0200) Auto-Detected
> Subject: Re: [Laszlo-user] Understanding memory analysis when using
> _LzDebug.whyAlive()
>
> [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.
>
>