GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||
GeezerVison is showing github.com — fix(runtime): charge the native memory of +0 objects once JS holds the last reference by edusperoni · Pull Request #515 · NativeScript/ios Conversation
Collaborator
The gap#507 charges an estimated native size (NSData length, UIImage/CGImage bitmap, CVPixelBuffer) only for objects JS likely owns: JS constructors, initializers, +1 returns and class factory methods. A wrapper retains its object until V8 collects the wrapper, though, so a +0 object that crosses into JS is shared with native only while the call runs: a block or callback argument, a JS-implemented override's parameters, a +0 return. Once the native caller lets go, the wrapper is the sole owner until GC, and V8 still sees a few dozen bytes.
Measured caseA worker receives a 205 KB
On a device, that growth is a jetsam risk. This PR makes the right-hand column happen without the manual call. DesignCandidates. In Deferred check point. The check runs in a
Callbacks often enter the isolate from a foreign thread: a block invoked on a dispatch queue takes the isolate's Locker on that queue's thread. The measured case is one. The native caller runs on that other thread, so the home loop has no point it can observe. Candidates recorded off the home thread are therefore due 16 ms later. A no-op Sole-owner test. At the check:
Only when all three hold is the estimate charged through #507's
Threading, gate and disposal. Increases only happen in Limits
TestsNew specs in
Negative control. With candidate recording disabled, exactly the 8 positive specs fail and the "does not charge" spec passes. Suite. NumbersTestRunner repro of the measured case: a native serial queue delivers a fresh 205 KB
This PR matches the manual charge. The later first GC in this harness compared with the app (30–40 s against ~10 s) shows in both the manual and the automatic runs, so it comes from V8's initial external-memory limit with little other allocation, not from the deferral.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions…e last reference A wrapper retains its object until V8 collects the wrapper, so a +0 object that reaches JS (a block or override argument, an instance method's return) is solely owned by its wrapper once the native caller lets go. V8 still saw a few dozen bytes for it: a worker receiving a 205 KB NSData per frame at 60 Hz grew past 1.4 GB without a single collection. - When a registered wrapper is first created for an object whose class has a size estimator, the object becomes a candidate in a bounded per-isolate list (4096); classes without an estimator cost one cached class lookup. Owned paths that charge right away drop their entry again. - Candidates are checked once, from a kCFRunLoopBeforeWaiting observer on the isolate's home run loop, ordered after UIKit's autorelease pool pop so the main thread's pool for the turn has drained. Candidates recorded on another thread (callbacks that enter the isolate from a dispatch queue) wait 16 ms for their native caller to let go, and a no-op EventLoop post makes an idle home loop run the pass that checks them. - A candidate is charged its estimate if its wrapper is still attached and the object's retain count is JS's own: the wrapper's retain plus one per live interop.bufferFromData buffer, which bufferFromData now counts on the wrapper. Collected or released wrappers, objects native still retains and immortal objects (constants, tagged pointers) are skipped. - Charging happens under the Locker on the home thread, behind the isolate pin and a cache validity check, and stops when execution is terminating; the observer is torn down first in ~Runtime.
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. This branch has not been deployedNo deployments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ReviewersNo reviewsUh oh!
There was an error while loading. Please reload this page. AssigneesNo one assignedLabels
None yet
ProjectsMilestoneNo milestoneDevelopmentSuccessfully merging this pull request may close these issues. Uh oh!
There was an error while loading. Please reload this page. Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later. | ||||||||||||||||||||||||||
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |