Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect available memory inside of a WebView

I'm building an app that contains a WebView that runs some JavaScript code. That JavaScript code is quite allocation heavy and can require a lot of memory.

Sometimes, the amount of required memory exceeds the amount JavaScript can require and crashes the Chromium process of the WebView which crashes my app.

I listen to onMemoryTrim in my application - but it is never called in this scenario on devices with more than 1GB of memory. (Not even with TRIM_MEMORY_RUNNING_LOW).

Is there any way I could detect my WebView is running low on memory and either kill it or let it know (so it can free memory)?

I've tried polling performance.memory but it did not work. The following script crashes the WebView if executed in it:

var a = [];

var kek = () => {
  var b = [];
  for(var i = 0; i < 1024 * 1024 * 2; i++) b.push(Math.random());
  return b;
}

var ival = setInterval(() => {
  let m = performance.memory;
  if(m.jsHeapSizeLimit - m.usedJSHeapSize < 1e5) {
    console.log("Memory limited")
  } else {
    a.push(kek());
  }
});

Is there any way to detect memory is about to run out so I can handle it gracefully without the app crashing?

like image 840
Benjamin Gruenbaum Avatar asked Jul 28 '17 21:07

Benjamin Gruenbaum


1 Answers

I have discussed this with the Chromium team and the Android team and at the moment (they think and I believe them) that this is impossible.

Sometimes, the amount of required memory exceeds the amount JavaScript can require and crashes the Chromium process of the WebView which crashes my app.

You can however catch out of memory crashes in Android 8.0+ using the new termination handle API. So this works around my problem by not having to check the available memory required in the first place.

By overriding onRenderProcessGone - we get to catch the bug and recreate the WebView.

like image 192
Benjamin Gruenbaum Avatar answered Nov 16 '22 23:11

Benjamin Gruenbaum