02-28-2022 01:49 - edited 02-28-2022 08:47
02-28-2022 01:49 - edited 02-28-2022 08:47
I have reached the memory limit in my watchface and am investigating the causes.
I noticed that the call document.getElementById, without other invocation on the returned svg element, produce memory load that will not be recovered by garbage collector.
After call getElementById for 72 svg empty elements 11% of memory is allocated and never released
If you uncomment the line ...getElementById("arc") memory usage increase again 11% so in total will consume 22% memory that will never been released.
Output in console:
[14:42:01] App: Hello world!
[14:42:01] App: MEM:9.5% start 12584/131064 12360-12376
[14:42:01] App: MEM USAGE index.ENTER...................9.7% 9.7% 12768 / 131064
[14:42:01] App: MEM USAGE index.EXIT....................1.2% 10.9% 14296 / 131064
[14:42:03] App: MEM:22.6% 29768/131064 12360-29632
[14:42:05] App: MEM:22.8% 30056/131064 12360-29928
[14:42:07] App: MEM:23.1% 30344/131064 12360-30216
[14:42:09] App: MEM:23.3% 30632/131064 12360-30504
[14:42:11] App: MEM:23.5% 30920/131064 12360-30792
[14:42:13] App: MEM:23.7% 31208/131064 12360-31080
[14:42:15] App: MEM:23.9% 31496/131064 12360-31368
[14:42:17] App: MEM:24.2% 31784/131064 12360-31656
[14:42:19] App: MEM:24.4% 32072/131064 12360-31944
[14:42:21] App: MEM:24.6% 32360/131064 12360-32232
[14:42:23] App: MEM:24.8% 32648/131064 12360-32520
[14:42:25] App: MEM:21.4% 28136/131064 12360-32520
[14:42:27] App: MEM:21.6% 28424/131064 12360-32520
[14:42:29] App: MEM:21.8% 28696/131064 12360-32520
[14:42:31] App: MEM:22.0% 29000/131064 12360-32520
[14:42:33] App: MEM:22.3% 29288/131064 12360-32520
[14:42:35] App: MEM:22.5% 29576/131064 12360-32520
[14:42:37] App: MEM:22.7% 29864/131064 12360-32520
Is my code wrong?
app/index.js
console.log('Hello world!'); import * as memoryMonitor from "./memoryMonitor"; memoryMonitor.initMemoryPressureMonitor(); memoryMonitor.start(); let mu=memoryMonitor.memUsageStart("index"); import * as document from "document"; let sectors=[ "sun" , "cloud" , "prec" , "wind" , "gust" , "ice" , ]; setUi(0) function setUi(from){ for (let i=from;i<72;i++){ let sectorUi=document.getElementById("s_"+i); let offset=0; for (let s=0;s<sectors.length;s++){ let sector=sectors[s]; let sect= sectorUi.getElementById(sector); //let arc=sect.getElementById("arc") //TODO set ui sect=null; //arc=null; }; sectorUi=null if (i-from>2){ setTimeout(()=>{ setUi(i); },1); break; } } } mu("EXIT")
import { memory } from "system"; export function initMemoryPressureMonitor(){ memory.monitor.onmemorypressurechange=()=>{ let msg=`Mem is ${memory.monitor.pressure} ${(memory.js.used / memory.js.total * 100).toFixed(1)}%`; switch (memory.monitor.pressure){ case "normal": console.log(msg); break; case "high": console.warn(msg); break; case "critical": console.error(msg); break; } } } let min=999999; let max=0; const memUsageEnabled=true; const memUsageDetailsEnabled=true; let lastMemUsage=0; export function start(){ memStats("start"); setInterval( memStats,2000); } export function memStats(desc) { if (!desc) desc=""; min=Math.min(min,memory.js.used); max=Math.max(max,memory.js.used); let msg = `MEM:${(memory.js.used / memory.js.total * 100).toFixed(1)}% ${desc} ${memory.js.used}/${memory.js.total} ${min}-${max}`; console.warn(msg); return msg; } export function memUsageStart(id){ if (!memUsageEnabled) return ()=>{}; printMemUsage(id,"ENTER"); return (desc)=>memUsage(id,desc); } function pad(s,len,filler){ let diff=len-s.length; if (len>0){ for (let i=0;i<diff;i++) s+=filler; } return s; } export function memUsage(id,desc) { if (!desc){ printMemUsage(id,"EXIT"); }else{ if (!memUsageEnabled||!memUsageDetailsEnabled) return; printMemUsage(id,desc); } } function printMemUsage(id,desc){ let currentMemUsage=memory.js.used let msg = pad(`MEM USAGE ${id}.${desc}`,40,'.') + pad(`${((currentMemUsage-lastMemUsage)/ memory.js.total * 100).toFixed(1)}%`,10," ")+`${(currentMemUsage / memory.js.total * 100).toFixed(1)}% ${currentMemUsage} / ${memory.js.total} `; console.error(msg); lastMemUsage=currentMemUsage }
<svg> <defs> <symbol id="alert"> </symbol> <symbol id="sector"> <use id="sun" href="#alert" /> <use id="cloud" href="#alert" /> <use id="prec" href="#alert" /> <use id="gust" href="#alert" /> <use id="wind" href="#alert" /> <use id="ice" href="#alert" /> </symbol> <symbol id="alerts"> <use href="#sector" id="s_0"/> <use href="#sector" id="s_1"/> <use href="#sector" id="s_2"/> <use href="#sector" id="s_3"/> <use href="#sector" id="s_4"/> <use href="#sector" id="s_5"/> <use href="#sector" id="s_6"/> <use href="#sector" id="s_7"/> <use href="#sector" id="s_8"/> <use href="#sector" id="s_9"/> <use href="#sector" id="s_10"/> <use href="#sector" id="s_11"/> <use href="#sector" id="s_12"/> <use href="#sector" id="s_13"/> <use href="#sector" id="s_14"/> <use href="#sector" id="s_15"/> <use href="#sector" id="s_16"/> <use href="#sector" id="s_17"/> <use href="#sector" id="s_18"/> <use href="#sector" id="s_19"/> <use href="#sector" id="s_20"/> <use href="#sector" id="s_21"/> <use href="#sector" id="s_22"/> <use href="#sector" id="s_23"/> <use href="#sector" id="s_24"/> <use href="#sector" id="s_25"/> <use href="#sector" id="s_26"/> <use href="#sector" id="s_27"/> <use href="#sector" id="s_28"/> <use href="#sector" id="s_29"/> <use href="#sector" id="s_30"/> <use href="#sector" id="s_31"/> <use href="#sector" id="s_32"/> <use href="#sector" id="s_33"/> <use href="#sector" id="s_34"/> <use href="#sector" id="s_35"/> <use href="#sector" id="s_36"/> <use href="#sector" id="s_37"/> <use href="#sector" id="s_38"/> <use href="#sector" id="s_39"/> <use href="#sector" id="s_40"/> <use href="#sector" id="s_41"/> <use href="#sector" id="s_42"/> <use href="#sector" id="s_43"/> <use href="#sector" id="s_44"/> <use href="#sector" id="s_45"/> <use href="#sector" id="s_46"/> <use href="#sector" id="s_47"/> <use href="#sector" id="s_48"/> <use href="#sector" id="s_49"/> <use href="#sector" id="s_50"/> <use href="#sector" id="s_51"/> <use href="#sector" id="s_52"/> <use href="#sector" id="s_53"/> <use href="#sector" id="s_54"/> <use href="#sector" id="s_55"/> <use href="#sector" id="s_56"/> <use href="#sector" id="s_57"/> <use href="#sector" id="s_58"/> <use href="#sector" id="s_59"/> <use href="#sector" id="s_60"/> <use href="#sector" id="s_61"/> <use href="#sector" id="s_62"/> <use href="#sector" id="s_63"/> <use href="#sector" id="s_64"/> <use href="#sector" id="s_65"/> <use href="#sector" id="s_66"/> <use href="#sector" id="s_67"/> <use href="#sector" id="s_68"/> <use href="#sector" id="s_69"/> <use href="#sector" id="s_70"/> <use href="#sector" id="s_71"/> </symbol> </defs> <use href="#alerts" id="alerts"/> </svg>
Answered! Go to the Best Answer.
02-28-2022 12:10
02-28-2022 12:10
I'm afraid it's normal for getElement... to hold on to memory. My assumption is that it creates JS objects that correspond to the SVG elements it's applied to, and the system retains those objects internally so it doesn't have to recreate them every time getElement... is called for the same element.
I've found that I can't have many more than about 300 elements in a project (depending on code size). You seem to have at least 71*6 elements, so the issue could be as simple as that.
02-28-2022 07:27
02-28-2022 07:27
Hi @alessandroame - presumably you are loading to a pre Versa 2 watch.
Garbage collection may not happen immediately.
There may be other issues raising the memory_err in SDK 4.3 that weren't there in SDK 4.2
Try in the OS Simulator 0.9.0 and see if the problem is resolved.
Something may be wrong with SDK 4.3
Author | ch, passion for improvement.
02-28-2022 08:09
02-28-2022 08:09
My environment:
The scenario applies also to real device.
As you can see in the output @ [14:42:25] garbage collector was triggered
02-28-2022 09:29
02-28-2022 09:29
@alessandroame if your program will work with it, try using SDK 5 in your package.json,
The same error may be in 6 that's in 4.3 as they were released together.
Author | ch, passion for improvement.
02-28-2022 12:10
02-28-2022 12:10
I'm afraid it's normal for getElement... to hold on to memory. My assumption is that it creates JS objects that correspond to the SVG elements it's applied to, and the system retains those objects internally so it doesn't have to recreate them every time getElement... is called for the same element.
I've found that I can't have many more than about 300 elements in a project (depending on code size). You seem to have at least 71*6 elements, so the issue could be as simple as that.
02-28-2022 12:24 - edited 02-28-2022 12:31
02-28-2022 12:24 - edited 02-28-2022 12:31
@Guy_ Same result with sdk5
02-28-2022 12:30 - edited 02-28-2022 12:31
02-28-2022 12:30 - edited 02-28-2022 12:31
@Gondwana I agree with you but I was hoping I was wrong.
02-28-2022 13:13
02-28-2022 13:13
If you didn't need all of those elements available simultaneously, you might be able to use the document API to load a different .view. I think that would free memory allocated to previous elements, and it's the only way I suspect to do so.
But that probably won't suit your concept.
03-01-2022 00:19
03-01-2022 00:19
I will find an other way.
Thanks to all for your posts.. you make the community alive, in the past it was a silent desert here.
03-01-2022 00:24
03-01-2022 00:24
There's also a community here.