We have slowly been stripping out functionality in our app to try to target whatever is causing the memory leaks… and are now down to a pretty bare bones app …
In addition to the plugins Ionic installs by default, StatusBar and Splashscreen, we additionally installed the Media and File plugins. Ionic Native 3.
Our app instantiates and loads a tabs page that has 2 tabs.
One tab loads an empty page.
The second tab, when selected, fires ionViewDidEnter()
which instantiates the File and Media plugins:
import { Component } from '@angular/core';
import { IonicPage, ViewController } from 'ionic-angular';
import { File } from '@ionic-native/file';
import { MediaPlugin, MediaObject } from '@ionic-native/media';
/**
* Generated class for the Home page.
*
* See http://ionicframework.com/docs/components/#navigation for more info
* on Ionic pages and navigation.
*/
@IonicPage()
@Component({
selector: 'page-home',
templateUrl: 'home.html',
})
export class Home {
private audioInstanceRecord:MediaObject;
private audioRecordToInternalURL;
private audioRecordStatusCode:number = 0;
private pageStatus:string = "";
constructor(private viewCtrl: ViewController,
private file: File,
private mediaPlugin: MediaPlugin) {
}
createAFile() {
this.file.createFile(this.file.documentsDirectory, 'audio.m4a', true)
.then(res => this.audioRecordSetFilePaths(res))
.catch(err => console.log('create file error:', err));
}
audioRecordSetFilePaths(data) {
this.audioRecordToInternalURL = data.toInternalURL();
this.mediaPlugin.create(this.audioRecordToInternalURL,(status)=>{
this.audioRecordStatusCode = status
}).then(file => this.audioInstanceRecord = file)
.catch(e => console.log('Error opening media file', e));
}
startRecord(){
this.audioInstanceRecord.startRecord();
this.pageStatus = "recording...";
}
stopRecord(){
this.audioInstanceRecord.stopRecord();
this.pageStatus = "done recording.";
}
play() {
this.audioInstanceRecord.play();
this.pageStatus = "playing audio..."
}
pause() {
this.audioInstanceRecord.pause();
this.pageStatus = "paused audio."
}
dismiss() {
let data = {foo: 'bar'};
this.viewCtrl.dismiss(data).then(()=> {
});
}
ionViewDidEnter() {
this.createAFile();
}
ionViewWillLeave() {
this.audioInstanceRecord.release();
this.audioInstanceRecord = null;
this.file.removeFile(this.file.documentsDirectory, 'audio.m4a')
.then(res => console.log('remove:', res))
.catch(err => console.log('create file error:', err));
}
}
Which as you can see is pretty basic.
Now… NEVER MIND actually triggering those events, startRecord, Play etc …
WITHOUT even doing that …
JUST SWITCHING TABS back and forth ADDS to the Memory usage … approximately ~4MB with each time this second tab instantiates …
We release the audio instance on exiting among other things in there …
If something that simple adds to Memory usage thats never released … eventually the app WILL crash.
So with that i ask … and with all due respect … what good is Ionic if this is the case??
I’d LOVE for someone to tell me what i might be doing wrong …
But separate from this simple example … Our app is much more complex … and the memory usage is ENORMOUS … We have followed all conventions with regard to unsubscribing to observables where necessary, nulling out Arrays and properties where necessary … Honestly, it all just seems completely un-realistic to try and deploy an Ionic / Angular app into the real world with problems like this … i dunno … we are just VERY discouraged by all of this … and its not like we can really ask Ionic for help directly… they have enough on their hands … never mind memory leaks.
Here is our setup…
Cordova CLI: 6.5.0
Ionic Framework Version: 3.0.1
Ionic CLI Version: 2.2.3
Ionic App Lib Version: 2.2.1
Ionic App Scripts Version: 1.3.0
ios-deploy version: 1.9.1
ios-sim version: 5.0.13
OS: macOS Sierra
Node Version: v7.9.0
Xcode version: Xcode 8.3 Build version 8W120l