NativeScript: [Android] memory leak for Images
In case an image source has been changed in several times there is java.lang.OutOfMemoryError exception.
java.lang.RuntimeException: An error occured while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:300) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355) at java.util.concurrent.FutureTask.setException(FutureTask.java:222) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:818) Caused by: java.lang.OutOfMemoryError: Failed to allocate a 8032012 byte allocation with 1496439 free bytes and 1461KB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method) at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:634) at org.nativescript.widgets.Async$Http$RequestResult.readResponseStream(Async.java:350) at org.nativescript.widgets.Async$Http$HttpRequestTask.doInBackground(Async.java:428) at org.nativescript.widgets.Async$Http$HttpRequestTask.doInBackground(Async.java:378) at android.os.AsyncTask$2.call(AsyncTask.java:288) at java.util.concurrent.FutureTask.run(FutureTask.java:237) … 3 more
here is the code witch I used
import {Component} from "@angular/core";
@Component({
selector: "my-app",
template: `
<StackLayout>
<Image src="{{src}}" stretch="fill" (tap)="change()"></Image>
</StackLayout>
`
})
export class AppComponent {
src;
constructor() {
this.change();
}
change() {
this.src = 'https://placekitten.com/1000/200' + parseInt('' + Math.random() * 9);
}
}
tns --version: 2.1.0 tns-core-modules: 2.2.0 tns-android 2.1.1
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 1
- Comments: 45 (17 by maintainers)
Commits related to this issue
- (Bugfix) Android Image memory leak, resolves #2571 — committed to colinskow/NativeScript by colinskow 8 years ago
Hello @jakethashi,
The OutOfMemory exception is caused by working with big images.
The thing is that Android can not handle big images well, so the developers should handle the way they are passing images to Android apps using caching techniques and cropping to lower the size. There are several plugins that are handling this issue (e.g. nativescript-image-cache-it and nativescript-fresco) and also you can check the multiple threads where this behaviour is discussed, like this one
Also. you can check image-cache module (for NativeScript core only)
p.s. I also noticed that you are using the latest modules with the previous version of our CLI - you can update your NativeScript to 2.2.0 (not related to your issue - you still have to handle the way you are managing your images)
I am curious if this is an open issue or if it has been fixed? I am still seeing oom issues with android / nativescript 2.5.4 and loading images into a listview. I implemented a thumbnail so the images are just a few kilobytes no more than 6 load at a time. The list view refreshes based on a drag events or zoom feature of a map so the list view reloads rather quickly. We have tried resolving this with the FrescoDrawee library and that doesn’t seem to help.
While profiling another app we found two memory leaks that are fixed in master branch and will go live with 2.3.0. They were causing native widgets to stay forever in memory which leads to OOM. So in 2.3.0 OOM should be fixed (at most).
Now if you try to set src in a setInterval function you will still see OOM. Calling
recycleon the Bitmap solve this problem but there is no way to know when ImageSource can be safely recycled. For example using image-cache module results in exception that bitmap is recycled.ImageView current implementation uses image-source module to load images. This means that native bitmap can be collected only after JavaScript imageSource instance is collected. This is not exactly memory leak but more garbage synchronisation issue.
With fixes in 2.3.0 if you perform navigation you probably won’t see OOM Exception, we run JavaScript garbage collector when Java thread is idle… With the next release (probably 2.3.1) we are going to change the ImageView implementation so it won’t use image-source module but loads bitmaps directly in Java. This will allow Java garbage collector to release bitmaps once they are not used by ImageView widget.
I hope that this clarifies the problem.
@NickIliev without authentication I don’t think any data will be returned. I can send you test creds privately if you want? The image-garbage-collect isn’t actually doing anything / being triggered as nothing is being destroyed.
@colinskow The transition issue was causing all native views from current page to stay alive when you navigate forward or backward. So it will definitely help but I’m not sure it will be enough. I’m in the process of completing Image refactoring so once it is in the master branch OOM should be past 😃.
As for using the master - the easiest way will be to install tns-core-modules@next.