android: [Marking Mode: None]: Crash: Attempt to use cleared object reference

Please, provide the details below:

Via crashlytics we have been getting reports of crashes of the type com.tns.NativeScriptException: Attempt to use cleared object reference id=48048(com.tns.NativeScriptException: Attempt to use cleared object reference id=48048 com.tns.Runtime.getJavaObjectByID(Runtime.java:893)

Did you verify this is a real problem by searching Stack Overflow and the other open issues in this repo?

Other closed bugs reference the same or similar issues (latest was closed for 3.0.0).

Please provide the following version numbers that your issue occurs with:

  • CLI: 3.2.1
  • Cross-platform modules: 3.2.0
  • Runtime(s): 3.2.0
  • Plugin(s):
    • nativescript-angular: 4.4.1
    • nativescript-fabric: 0.3.1
    • nativescript-pro-ui: 3.2.0
    • nativescript-google-maps-sdk: 2.3.3

Built using webpack (npm run ns-bundle --android --build-app --snapshot --clean --release) Also using in app/package.json:

  "android": {
    "v8Flags": "--expose_gc",
    "markingMode": "none"
  }

Did the error happen while the app was being constructed? (buildtime error)

No

Did the error happen while the app was executing? (runtime error)

Yes, but I haven’t reproduced it myself. Just numerous similar stack traces being sent via crashlytics/fabric.

e.g.

#0. Crashed: main: 0 0 0x0000000000000000
       at .Error: com.tns.NativeScriptException: Attempt to use cleared object reference id=48048(com.tns.NativeScriptException: Attempt to use cleared object reference id=48048
    com.tns.Runtime.getJavaObjectByID(Runtime.java:893)
    com.tns.Runtime.callJSMethodNative(Native Method)
    com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1084)
    com.tns.Runtime.callJSMethodImpl(Runtime.java:966)
    com.tns.Runtime.callJSMethod(Runtime.java:953)
    com.tns.Runtime.callJSMethod(Runtime.java:937)
    com.tns.Runtime.callJSMethod(Runtime.java:929)
    com.tns.gen.java.lang.Runnable.run(Runnable.java:10)
    android.os.Handler.handleCallback(Handler.java:751)
    android.os.Handler.dispatchMessage(Handler.java:95)
    android.os.Looper.loop(Looper.java:154)
    android.app.ActivityThread.main(ActivityThread.java:6780)
    java.lang.reflect.Method.invoke(Native Method)
    com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
    com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386):1)
       at . ... (repeats with slight differences)

full trace at https://pastebin.com/JEGTYrpx

Please tell us how to recreate the issue in as much detail as possible.

Unknown. Possibly random.

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 5
  • Comments: 61 (21 by maintainers)

Commits related to this issue

Most upvoted comments

I’m reopening the issue as the problem is real and is not resolved. Our plans for after the 4.0 release are to focus on making plugins maintained by NativeScript compatible with markingMode: none. Cases like this one will be useful for us to validate whether we have covered all cases.

Hi,

Thanks for your reply.

No unfortunately, I’m not authorized to put a demo example.

But really it’s nothing fancy at all… it’s a regular RadListView as described into Nativescript docs for Angular.

I’ve just added a <Image> tag into the list item into a GridLayout, there’s no external plugin or whatever.

If I remove the image it works just fine…so it’s clearly linked to a nullable element at mobile platform side.

If I turn markingMode to full it also not crash anymore…but indeed poor performance after some times.

I’ve also tried using a simple ListView component (not radlist)… but it’s the same scroll behavior behind…If a scroll too fast…then randomly it will crash the app.

BUT,… If a put a simple Gridlayout as a wrapper around the Image tag with a *ngIf directive to verify if src can be fulfilled it seems to not crash anymore.

So If no src data … no Image element into the template and no link to android glide or Picasso adapter or something.

I will continue with that fix…and let you know If I get other JNI crash from android.

Thanks anyway. Lo.

Le 17 févr. 2020 à 10:39, Nick Iliev notifications@github.com a écrit :

@lostation https://github.com/lostation provide a demo application that reproduces the issue so we could investigate further. Simply using a RadListView with a lot of images is not reproducing the issue on my side - are you sure you are not using other elements/layouts/plugins inside the item templates?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/NativeScript/android-runtime/issues/887?email_source=notifications&email_token=ACX5G6WPDYHXZWDKH3UWLIDRDJLMZA5CNFSM4EFXU3VKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEL5WUHY#issuecomment-586902047, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACX5G6WUZJN5DTPV5HX4WE3RDJLMZANCNFSM4EFXU3VA.

This bug actually references in lots of these cases in this big long running issue has already been fixed. This unfortunately is not a fix one and always fixed issue. So you get people adding to this bug every so often because they run into a another case of buggy code that causes it… (And unfortunately when making native code bindings, it is easy to create code that can cause this issue…)

It is related to having two Garbage Collection engines, if the Android native side no longer thinks it has a valid reference to the object, but the JS engine believes it does then this issue can occur. Almost always happens in Android NATIVE JAVA callback handlers.

So this issue, in a lot of cases, a plugin author has written something incorrectly in their plugin, it will cause this issue to occur. You use XXX plugin, your app then fails with this error; issue wasn’t framework – issue was plugin. I know several apps that I have helped with or nStudio has helped with that has a insignificant crash rate – this issue is really not that wide spread; and is typically issue when using certain plugins that aren’t maintained…

So the “when” it occurs and “why” it occurs is different for probably most of us on this issue. And in a lot of the prior cases reported on this thread the bug has been fixed in those code areas… I’ve even seen the Core team report a fix to some of the plugins over the years this bug has been open, way above and beyond what they need to. So you need to understand this bug is a collection of cases that cover a specific symptom that looks the same, but isn’t…

We’re still seeing Attempt to use cleared object reference errors, quite often. Has any work been done to improve the error message? It’s hard helping you guys when we have no pointers to the cause.

This should be a priority IMHO.

Indeed, this is one of the things we will focus on for 4.1.

@NathanaelA

Just because markingmode:“none” causes it to happen more often doesn’t mean that the normal GC doesn’t cause it to happen in other timing.

That’s incorrect. When marking mode is set, it changes the way GC works, so any related GC issues will be completely different.

Actually I would tend to disagree with you; I do realize the M:N totally changes the way the GC works; but if something is being collected too soon under M:N; that doesn’t mean under the normal GC the issue retaining the value may also still exists and the normal GC might collect it too soon also under different memory loads. If their isn’t a proper ref to hold it; then it can be GC’d under both engines. This was my only point; without knowing why M:N collected it too soon, doesn’t mean that the normal GC won’t collect it too soon also. I still see reports weekly on the Attempt to use cleared object reference id in the normal GC engine; so unfortunately there are still premature GC collection issues in the normal GC engine also…


I closed the issue, just as I said “because of the lack in activity”.

Closed to me says nothing is going to happen with it or invalid report.

See this is where I totally disagree with this stance, you are closing a VALID bug report w/o anything done on it. I know it looks good to management; but it is imho totally wrong stance. This issue isn’t magically resolved by you closing it; and the bug is 100% valid issue UNTIL M:N is either depreciated and removed or the bug itself is fixed. Since M:N is still a valid experimental feature; the valid bugs that go with it should also be retained 😉

Now that it’s post 4.0, it would be really great news if you were working on the markingMode changes for the plug-ins. NS is an excellent system, well designed and with a great developer experience. Unfortunately the current choice between slowness (markingMode not set) and crashes (markingMode set to none) makes it difficult to ship on Android.

Hi @yyankov thank you for your feedback. As I previously explained this error is caused by the fact your business logic encloses a native object, that’s already collected. To put it more simply, you need to find the js object that’s cleared and persist it in javascript in some of the ways I mentioned previously.

When I look at the error you posted, I can point you in the right direction: ListViewAdapter.onCreate it’s probably an object enclosed by this function, which has a javascript counterpart.

Thanks. If that is the extent of it, then it should be less of a problem to track things down in my code than I expected. Less easy are nativescript-pro-ui since it does not have source available. And nativescript-angular since my app is an angular one this will be used heavily by every screen (and a quick look though the stacktrace I posted above reveals EmulatedRenderer.NativeScriptRenderer.insertBefore, which I believe corresponds to this line https://github.com/NativeScript/nativescript-angular/blob/42e438ce4b206ff96fb2fe31e9968fcfc555f5a6/nativescript-angular/renderer.ts#L101)

Unfortunately markingMode: none makes a huge difference. Otherwise I would have never deployed with it in the first place, and could simply turn it off now. The random multi-second (and sometimes minutes) long UI freezes did not make for a good user experience.

@ivandejesus See https://github.com/NativeScript/NativeScript/issues/7867 for a possibly working hack if you are in this case 😃

When Java is calling a method and a reference is passed that… the Java instance has been collected? That throws null reference exception, right? It will not try to marshal it to its JavaScript instance. But I agree that we need very good error reporting. When these errors occurs we often have the Java instance and can provide information from it as well as full stack trace sandwich and if possible the JS class source…

After 5.1 all plugins owned by the NativeScript Team should be compatible with the markingMode: none option in their latest versions. I see that the app in question is using the nativescript-pro-ui, so upgrading to the latest packages of the nativescript-ui-* might help partially for this issue as well.

There is a pattern: at . com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)(com.tns.NativeScriptException: Attempt to use cleared object reference id=48048 If you collect the messages between at . and (com.tns.NativeScriptException ... it looks like:

Error: com.tns.NativeScriptException: Attempt to use cleared object reference id=48048
    com.tns.Runtime.getJavaObjectByID(Runtime.java:893)
    com.tns.Runtime.callJSMethodNative(Native Method)
    com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1084)
    com.tns.Runtime.callJSMethodImpl(Runtime.java:966)
    com.tns.Runtime.callJSMethod(Runtime.java:953)
    com.tns.Runtime.callJSMethod(Runtime.java:937)
    com.tns.Runtime.callJSMethod(Runtime.java:929)
    com.tns.gen.java.lang.Runnable.run(Runnable.java:10)
    android.os.Handler.handleCallback(Handler.java:751)
    android.os.Handler.dispatchMessage(Handler.java:95)
    android.os.Looper.loop(Looper.java:154)
    android.app.ActivityThread.main(ActivityThread.java:6780)
    java.lang.reflect.Method.invoke(Native Method)
    com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
    com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)

    at Label.ViewBase._setupUI (<embedded>:57858:49)
    at StackLayout.ViewBase._addViewCore (<embedded>:57782:18)
    at StackLayout.ViewBase._addView (<embedded>:57760:14)
    at StackLayout.LayoutBaseCommon.addChild (<embedded>:65654:14)
    at ViewUtil.insertToLayout (<embedded>:54934:20)
    at ViewUtil.addToVisualTree (<embedded>:54915:18)
    at ViewUtil.insertChild (<embedded>:54883:18)
    at EmulatedRenderer.NativeScriptRenderer.insertBefore (file:///data/data/org.nativescript.redacted/files/app/bundle.js:45438:23)
    at execRenderNodeAction (<embedded>:9407:22)
    at visitRenderNode (<embedded>:9378:13)

The full log has javascript traces: StackLayout.ViewBase._addViewCore (<embedded>:57782:18) at Label.ViewBase._setupUI (<embedded>:57858:49)(com.tns.NativeScriptException: Attempt to use cleared object reference id=48048 at ViewUtil.insertToLayout (<embedded>:54934:20)(com.tns.NativeScriptException: Attempt to use cleared object reference id=48048

Hi everybody, @gsmedley @etabakov @NathanaelA

There is a class of “Attempt to use cleared object reference” errors that is thrown out there, here is some insight on the design of markingMode: "none".

  1. JavaScript instances as long as they are alive (e. g. can not be GCed) will keep strong references to the Java instances.
  2. When JavaScript instance becomes eligible for collection, it will change the strong reference to a weak reference to the Java instance. From that point on the JavaScript instance will be “revived” as long as the Java instance is not collected.
  3. Only after the Java instance is collected, the JavaScript instance will be let to be collected.

This means that when markingMode: "none" is enabled the JavaScript instances will always live longer than the Java instances. Also as long as something holds the JavaScript instances alive (on stack, on global, on the module exports, or a function that is exported captures stuff in its closure etc.) the Java instances will survive.

So any error that happen, related with the Java instance being prematurely collected, should be due to JavaScript trying to call to Java. For example if you call method on an object, and that object was already collected, you should get a JavaScript callstack, and fixing errors having this callstack should be easy. The error should be similar to the following screenshot: image So once you get that, you as developer should pretty much figure out of the JavaScript callstack which instance was collected too early, go up the stuck (as much as possible) and retain somehow any listeners, or java objects that doesn’t seem to have their JavaScript instances retained long enough. (we need proper article on this one)

On the other hand the error report for failed methods seem fine (you have JavaScript stack) but the:

#0. Crashed: main: 0 0 0x0000000000000000
       at .Error: com.tns.NativeScriptException: Attempt to use cleared object reference id=48048(com.tns.NativeScriptException: Attempt to use cleared object reference id=48048
    com.tns.Runtime.getJavaObjectByID(Runtime.java:893)

kind of errors are total no-go.

The {N} Android team should probably figure out where these Attempt to use cleared object reference are thrown: https://github.com/NativeScript/android-runtime/blob/f88bfe069fd07a7ae561978ab4d97737cfc01603/test-app/runtime/src/main/java/com/tns/Runtime.java#L897

Figure out this getJavaObjectByID is only used from C++: https://github.com/NativeScript/android-runtime/blob/7897e2dc5a4b0a819ce1ce549bb86d6d6e2c40e3/test-app/runtime/src/main/cpp/ObjectManager.cpp#L30

And that’s why the Java callstack above seems lacking enough information. Following the “used by” chain you end up in NewWeakGlobalRefCallback then in:

https://github.com/NativeScript/android-runtime/blob/7897e2dc5a4b0a819ce1ce549bb86d6d6e2c40e3/test-app/runtime/src/main/cpp/ObjectManager.cpp#L25

The cache is initialized with this, and this cache on the other hand is used only in the ObjectManager GetJavaObjectByID:

https://github.com/NativeScript/android-runtime/blob/7897e2dc5a4b0a819ce1ce549bb86d6d6e2c40e3/test-app/runtime/src/main/cpp/ObjectManager.cpp#L134

Which is then used by GetJavaObjectByJsObject: https://github.com/NativeScript/android-runtime/blob/7897e2dc5a4b0a819ce1ce549bb86d6d6e2c40e3/test-app/runtime/src/main/cpp/ObjectManager.cpp#L79

GetJavaObjectByJsObject is called on places where the runtime is marshalling arguments for transition from JavaScript to Java. The errors for figuring out the “this” in a method call is well handled (like the screenshot above) but then, GetJavaObjectByJsObject is also used in:

https://github.com/NativeScript/android-runtime/search?q=GetJavaObjectByJsObject&type=Code

  • FieldAccessor.cpp
  • ArrayBufferHelper.cpp
  • ArrayElementAccessor.cpp
  • JsArgConverter.cpp
  • etc.

Every single place where it is used, we have isolate that is available and a JavaScript callstack should be available somewhere there, but the generated NativeScriptException seems to hide it.

With that said (if you choose to proceed with markingMode: none), the android runtime will have to do some advancements in the error reporting here. Since the errors will be random and hard to reproduce the error messages should be enough to locate and fix potential problems. These errors should be collectible by error reporting services (android crash reports? firebase?). Only when this is done we will be able to provide the “how to fix”.

@daveware-nv – Well, I tend to think it should stay open as long as the bug exists. Just because markingmode:"none" causes it to happen more often doesn’t mean that the normal GC doesn’t cause it to happen in other timing. I still get reports of random GC caused crashes; it isn’t happening as much as it was; but once a month for a low use app is still too much.

In addition since markingmode:none hasn’t been depreciated (but still in consideration(?) for a solid release); then this bug has should at a minimum stay open until it is fixed or markingmode:none is removed from the engine.

@Plamen5kov - I’m not sure this should be closed; as the issue still exists.

And by the way, is in the onCreateViewHolder of the ListViewWrapperAdapter, and that actually is in the Nativescript-Pro-UI — not his code… So in this case the error is 100% a Telerik/Progress issue; not something he can easily fix…