Skip to content

Commit 350090c

Browse files
authored
Merge pull request #744 from NativeScript/pete/fix-gc-issue-no-weakref
Fix #720 GC issue - No weak ref found
2 parents 7070b2f + 21c8834 commit 350090c

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

runtime/src/main/jni/ObjectManager.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,10 @@ void ObjectManager::MarkReachableObjects(Isolate* isolate, const Local<Object>&
460460
NativeScriptExtension::ReleaseClosureObjects(closureObjects);
461461
}
462462

463+
if (o->IsArray()) {
464+
MarkReachableArrayElements(o, s);
465+
}
466+
463467
auto proto = o->GetPrototype();
464468
if (!proto.IsEmpty() && !proto->IsNull() && !proto->IsUndefined() && proto->IsObject()) {
465469
s.push(proto);
@@ -518,6 +522,19 @@ void ObjectManager::MarkReachableObjects(Isolate* isolate, const Local<Object>&
518522
} // while
519523
}
520524

525+
void ObjectManager::MarkReachableArrayElements(Local<Object> &o, stack<Local<Value>> &s) {
526+
auto arr = o.As<Array>();
527+
528+
int arrEnclosedObjectsLength = arr->Length();
529+
for (int i = 0; i < arrEnclosedObjectsLength; i++) {
530+
auto enclosedElement = arr->Get(i);
531+
532+
if (!enclosedElement.IsEmpty() && enclosedElement->IsObject()) {
533+
s.push(enclosedElement);
534+
}
535+
}
536+
}
537+
521538
void ObjectManager::OnGcStartedStatic(Isolate* isolate, GCType type, GCCallbackFlags flags) {
522539
try {
523540
auto runtime = Runtime::GetRuntime(isolate);

runtime/src/main/jni/ObjectManager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,15 @@ class ObjectManager {
4949

5050
v8::Local<v8::Object> GetEmptyObject(v8::Isolate* isolate);
5151

52+
static void MarkReachableArrayElements(v8::Local<v8::Object> &o, std::stack<v8::Local<v8::Value>> &s);
53+
5254
enum class MetadataNodeKeys {
5355
JsInfo,
5456
CallSuper,
5557
END
5658
};
5759

60+
5861
private:
5962

6063
struct JSInstanceInfo {

test-app/app/src/main/assets/app/tests/testGC.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,29 @@ describe("Tests garbage collection", function () {
264264
gc();
265265
java.lang.System.gc();
266266
});
267+
268+
it("should keep array-enclosed objects alive after GC", function () {
269+
function createObjects(name) {
270+
var arr = new Array();
271+
arr.push(new com.tns.tests.Class1());
272+
273+
var cb1 = new com.tns.tests.Class1.Callback1(name, {
274+
getMessage: function() {
275+
var msg = arr[0].getMessage();
276+
return msg;
277+
}
278+
});
279+
280+
return com.tns.tests.Class1.Class2.printMessageWithDelay(cb1, 2 * 1000);
281+
}
282+
283+
expect(createObjects("Callback1")).toBe(true);
284+
expect(createObjects("Callback2")).toBe(true);
285+
expect(createObjects("Callback3")).toBe(true);
286+
287+
gc();
288+
java.lang.System.gc();
289+
})
267290

268291
it("should properly reintroduce Java object back in a callback", function () {
269292
function getTestObject() {

0 commit comments

Comments
 (0)