Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Search instead for 
Did you mean: 
ratish
Level 7

Garbage Collector and wait

Would like to understand if Garbage collector is dependent on the app idle condition. Why I am asking this is because i observed recently that if you give a very short wait period( say 5 ms ) then GC fails to release objects from memory even if we explicitly mark them as invalid.
Can anybody help me to understand the way the reference count GC works in brighscript and situations when it kicks off.
0 Kudos
7 Replies
EnTerr
Level 8

Re: Garbage Collector and wait

I don't think it is. As indirect indicator, Roku people have said to use getMessage() or wait(1) in tight loop when we were discussing timer granularity issues in 3xxx models, leading to wait(20) not being 20ms - if they knew certain wait was needed, they wouldn't suggest it.

Also from what i know, reference counting is used for B/S objects - meaning that the moment object references gets to 0, it's immediately released - no wait for GC run. And mark&sweep-ish GC is only called to collect cyclic structures, either explicitly or presumably when runs out of memory.

Can you show a code example that demonstrates the behavior?
0 Kudos
TheEndless
Level 7

Re: Garbage Collector and wait

One way to test for sure would be to explicitly add a RunGarbageCollector() call to the code where you're seeing the issue. If that doesn't fix it, then it's almost certainly not a garbage collection issue.
My Channels: http://roku.permanence.com - Twitter: @TheEndlessDev
Instant Watch Browser (NetflixIWB), Aquarium Screensaver (AQUARIUM), Clever Clocks Screensaver (CLEVERCLOCKS), iTunes Podcasts (ITPC), My Channels (MYCHANNELS)
0 Kudos
ratish
Level 7

Re: Garbage Collector and wait

My application has a event loop done using the wait.

wait(evenWaitTimeout, m.port) where the evenWaitTimeout is 5 ms.

Now in certain part of application I am making a called to server which returns me a huge json asycnhrounosuly. In on of the helper function i do parseJson and the object is then assigned with invalid. This is to test if GC releases the object. If I repeat this fetch and parsing along with making it invalid in the the above said 5 ms loop, i see that box reboots after a while. But if i make the evenWaitTimeout to say 50ms or 100ms, The box runs for long time.
0 Kudos
Roku Employee
Roku Employee

Re: Garbage Collector and wait

It is possible that we do garbage collection of large objects occurs in idle time periods, but generally, cleanup should occur as soon as something is dereferenced.

- Joel
0 Kudos
EnTerr
Level 8

Re: Garbage Collector and wait

"ratish" wrote:
Now in certain part of application I am making a called to server which returns me a huge json asycnhrounosuly. In on of the helper function i do parseJson and the object is then assigned with invalid. This is to test if GC releases the object. If I repeat this fetch and parsing along with making it invalid in the the above said 5 ms loop, i see that box reboots after a while. But if i make the evenWaitTimeout to say 50ms or 100ms, The box runs for long time.

I just did a test with parsing a big XML file - it is ~8MB in size, takes 3.7sec to parse on Roku3 and the resulting roXml object consists of over a million BSCs (BSc instances, i.e. objects) and if GC is invoked at that point, it takes ~2200ms to run with that many objects, a very noticeable pause. The choice of size was deliberate: it is almost the maximum Roku3 can parse - at least it cannot parse and hold in memory 2 objects of that size (if crashes if attempted).

Ok, so i took that xml and parsed it 20 times in a tight loop - no wait(), no idling, no GC calls in-between, no nothing. If memory was not reclaimed immediately, i expect it would have caused the player to crash - but it did not. Moreover gc at the end showed everything was tidy and no orphans were reclaimed.
[spoiler=experiment:1r0dmjs7]
BrightScript Debugger> gc
total number of current bscs: 3
number of root bscs: 3
number of orphaned bscs: 0
BrightScript Debugger> x = bench(18)
18 8126443 3995
BrightScript Debugger> tm = createObject("roTimeSpan"): ? runGarbageCollector(): ? tm.TotalMilliseconds()
COUNT: 1179648
ORPHANED: 0
ROOT: 5

2230
BrightScript Debugger> x = invalid
BrightScript Debugger> gc
total number of current bscs: 3
number of root bscs: 3
number of orphaned bscs: 0
BrightScript Debugger> for _=1 to 20: bench(18): end for
18 8126443 3531
18 8126443 3507
18 8126443 3511
18 8126443 3504
18 8126443 3511
18 8126443 3504
18 8126443 3509
18 8126443 3499
18 8126443 3510
18 8126443 3502
18 8126443 3512
18 8126443 3504
18 8126443 3505
18 8126443 3501
18 8126443 3509
18 8126443 3503
18 8126443 3507
18 8126443 3497
18 8126443 3503
18 8126443 3506
BrightScript Debugger> gc
total number of current bscs: 3
number of root bscs: 3
number of orphaned bscs: 0
[/spoiler:1r0dmjs7]
It therefore seems very unlikely the crashes you are experiencing are due to not enough wait(ms) for memory to be reclaimed. I did xml, you did json - theroretically routines may differ but i doubt that matters. My suspicion would be that you may be keeping >1 references to the same object (or have them hanging in stack etc).

A bit of nit-picking here but you said "the object is then assigned with invalid" - that's not possible, you cannot assign invalid to an object. You can assign invalid to the variable that points to the object, thus de-referencing the object and if nobody else points to it, it will be disposed of. But if for example there was something like `a = parseJSON(...): b = a: a = invalid` - that invalid assignment does nothing to free the object.
0 Kudos
ratish
Level 7

Re: Garbage Collector and wait

I tried this on XS box. On Roku 3, i did observe any memory shortage.
I am sure that after the parse json, i did not assign it to any other reference. But the 5ms time interval made the XS reboot.
0 Kudos
EnTerr
Level 8

Re: Garbage Collector and wait

"ratish" wrote:
I tried this on XS box. On Roku 3, i did observe any memory shortage.
I am sure that after the parse json, i did not assign it to any other reference. But the 5ms time interval made the XS reboot.

Hmm, i repeated my test on 2XS and it went fine as well, no reboot.
Mind you, i don't question crashes happen to you - just trying to pin-point it. I am interested to know if there are any memory shenanigans happening.
Could it be that you have one of these problematic 2XS boxes they keep talking in General's forum?
Can you test on a different 3xxx Roku or maybe 27xx (let's leave aside Roku3 for being dual-core-rugated).
0 Kudos