Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Need help with odd issue

I have a clock face for Versa 2 that installs and all settings function properly until another app is launched. After the app is closed, it returns to the clock face but nothing renders. 

 

I can swipe up into the today screens. I can swipe right and scroll through the apps and back again so I know the clock face is loaded. But again, only a black screen (the bg color).

 

When side loading the clock face, I am not getting any errors and I am unable to recreate the within the simulator.

 

SIDE NOTE: I have the exact same code for a Ionic clock face. The only thing different between them is the CSS xy coordinates of the components. I am having 0 issues with that face so I am thinking it is hardware memory related?

 

Any ideas?

Best Answer
0 Votes
12 REPLIES 12

It's very hard to diagnose without the project. When you switch to an app, the clock is unloaded. So it sounds like a javascript error on startup which prevents the rest of the code from running? I'd expect to see that in the console logs though.

 

If you can provide the UUID or source code, we can take a further look.

Best Answer
0 Votes

Thanks so much John. The UUID is 7b063cea-4548-4254-a936-3fce68dd1d52

Best Answer
0 Votes

I side-loaded it and was able to reproduce the error:

 

[3:11:07 PM]       App: App Started
[3:11:08 PM]       App: Fatal Jerryscript Error: ERR_OUT_OF_MEMORY

 

Unfortunately I'm unable to get any more details, but at least you can rip some code out and add the memory pressure stuff to see what's going on.

Best Answer
0 Votes

I was also getting that error before. I thought I had removed enough code to resolve it. The jerryscript error is the same reason I needed to duplicate it for each watch.

 

I wonder why I am not seeing it in the simulator anymore? Why would the Ionic version not have the same issue? More memory?

 

Best Answer
0 Votes

@JonFitbit  -  Is it possible to suspend access to this via the gallery? I need to fix the jerryscript errors and some are complaining that the face is not stalling during installation. 

 

Or do we need to take it down all together and then simply republish when it's fixed? I didn't see anywhere in the gallery manager to take it down myself....

Here is the UUID - 7b063cea-4548-4254-a936-3fce68dd1d52

Best Answer
0 Votes

@jomis003 wrote:

I was also getting that error before. I thought I had removed enough code to resolve it. The jerryscript error is the same reason I needed to duplicate it for each watch.

 

I wonder why I am not seeing it in the simulator anymore? Why would the Ionic version not have the same issue? More memory?

 


I have actually run into a kind of weird class of errors with the Versa 2,...

 

Because it is actually faster than the others, it tends to succeed at doing the wrong thing where the others do not. My specific problem was a race condition where Versa 2 would succeed at getting a settings update, before the init was fully completed. Ionic never had this issue, neither did the Versa 2 in simulation.

 

The Versa 2 has twice the memory of the Ionic.

 

function lm(){return("Mem:"+memory.js.used+"/"+memory.js.total+" Peak:"+memory.js.peak+" Pressure:"+memory.monitor.pressure)}
console.log(lm())

 

gives the result: [1:22:40 PM] App: Mem:53912/131064 Peak:53976 Pressure:normal 

when running to the Versa 2.

 

You could have some kind of memory hole happening that succeeds with Versa 2. Unfortunately, it's pretty unlikely to be a JavaScript size issue if the Versa 2 has a problem and the others do not.

 

A memory hole issue could be many things:

 

Do you clear interval variables before starting them?

Starting a new interval while it is still going throws away the original without reclaiming memory.

 

var spnInt
function spnMn(){
// other code
  clearInterval(spnInt)
  spnInt = setInterval(spnMn, 100)
}

 

Do you store document references?

These consume more memory than one would expect and may not be valid after an app restart.

 

Do you add event listeners any place other than during initialization?

Adding event listeners during events is a common problem. Adding the same listener routine multiple times adds multiple listeners that will all execute and will all consume memory.

 

Do you exit your program when your GUI is unloaded?

There are differences of opinion on this, but in my experience this doesn't always happen cleanly.

 

var ex=false
document.getElementById('mPage').onunload=function(e){
  ex=true
  me.exit()
}
clock.granularity='seconds'
clock.ontick=function (evt) {
  if (ex) return
//Clock tick handler
}

 

 

Hope this helps,

Reign

 

Best Answer
0 Votes

Thanks for all of the suggestions!

 

I am using one event handler but that is for an on exit function.

 

I am thinking my issue is with my css xy coordinates of the elements. Right now, the way it is configured is:

The user makes a selection in settings is recorded in array. There are 7 selections so the array could look like "1523467". Then each time a change happens to the array, a series of functions run for each of the numbers with if/then statements so that it reads:

 

if the array position is 1

then

element "a" x=10 and y=20

 

There is one of these for every digit in every position so it roledexes through each if/then statements to find the true one.

 

What I would like to do is be able to minimize the code by having one file with the xy coordinates and just call the needed coordinate position.

 

The way this is set up, I believe its just running it out of memory because if I remove some code, I can get rid of the Jerryscript errors.

 

Any ideas on how to consolidate?

 

 

Best Answer
0 Votes

That really shouldn't consume a lot of memory. Have you used the system API to check for memory exhaustion? (Output needs to be interpreted carefully because of deferred garbage collection.)

 

Any chance it's running out of stack space? That can also be reported as out of memory. This is harder to diagnose; try console.trace() and see how many layers of calls you're using.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

@jomis003 wrote:

Thanks for all of the suggestions!

 

I am using one event handler but that is for an on exit function.

 

I am thinking my issue is with my css xy coordinates of the elements. Right now, the way it is configured is:

The user makes a selection in settings is recorded in array. There are 7 selections so the array could look like "1523467". Then each time a change happens to the array, a series of functions run for each of the numbers with if/then statements so that it reads:

 

if the array position is 1

then

element "a" x=10 and y=20

 

There is one of these for every digit in every position so it roledexes through each if/then statements to find the true one.

 

What I would like to do is be able to minimize the code by having one file with the xy coordinates and just call the needed coordinate position.

 

The way this is set up, I believe its just running it out of memory because if I remove some code, I can get rid of the Jerryscript errors.

 

Any ideas on how to consolidate?

 

 


Not really clear on what you're doing here, but if you are returning values based on an index making an indexed object seems appropriate. If you are trying to save space, initializing from a json file is helpful.

 

Initializing from a file is important, because you otherwise end up paying for your variable memory twice, once as JavaScript code, the second as stack space.

 

I use something similar to the following as a heart rate zone lookup object:

function r(N){return fs.readFileSync("resources/"+N+".json", "json")}

var hr=r("hr")

 

The truncated hr.json file contents are:

{
  "s": 0,
  "z": {
    "out-of-range": {
      "f": "#df8",
      "p": 55,
      "n": "fat-burn",
      "m": 500
    },
    "below-custom": {
      "f": "#df8",
      "p": 55,
      "n": "custom",
      "m": 500
    },
    "fat-burn": {
      "f": "#ee0",
      "p": 125,
      "n": "cardio",
      "m": 500
    },
    // rest of the zones are here
  },
}

 

I think you could do a similar thing with your X and Y lookup values.

 

Regards,

Reign

Best Answer
0 Votes

Let me see if I can add some color. Here is a snippet of what my code is doing.

User makes a selection from a Select object in settings - they select the first option:

In the index.js

if (evt.data.key === "statSelection" && evt.data.newValue) {
    let value = (JSON.parse(evt.data.newValue).selected);
    var statArray = (JSON.stringify(value));
    var s1 = (JSON.stringify(value))[1];
    numOfStats.text = value.length; //off screen element
    position1.text = s1; //off screen element

    if (statArray.indexOf("0") != -1) {
      simpleSteps.showSteps();
    } else {
      simpleSteps.hideSteps();
    }
}

 Then it calls the showSteps function from another files which looks like...

export function showSteps() {
let numOfStats = document.getElementById("numOfStats");
let steps = document.getElementById("steps"), stepsArc = document.getElementById("stepsArc"), stepsIcon = document.getElementById("stepsIcon");
let position1 = document.getElementById("position1");

//STEPS IN POSITION 1\\   
  if (numOfStats.text === "1" && position1.text === "0") { //1 Stat
    steps.style.display = "inline", steps.x = 150, steps.y = 235, steps.style.fontSize = 50;
    stepsArc.style.display = "inline", stepsArc.x = 95, stepsArc.y = 160, stepsArc.width = 115, stepsArc.height = 115;        
    stepsIcon.style.display = "inline", stepsIcon.x = 127, stepsIcon.y = 245, stepsIcon.width = 45, stepsIcon.height = 45;
  } 
  if (numOfStats.text === "2" && position1.text === "0") { //2 Stats
    steps.style.display = "inline", steps.x = 70, steps.y = 235, steps.style.fontSize = 50;       
    stepsArc.style.display = "inline", stepsArc.x = 15, stepsArc.y = 160, stepsArc.width = 115, stepsArc.height = 115;        
    stepsIcon.style.display = "inline", stepsIcon.x = 47, stepsIcon.y = 245, stepsIcon.width = 45, stepsIcon.height = 45;
  }  
  if (numOfStats.text === "3" && position1.text === "0") { //3 Stats
    steps.style.display = "inline", steps.x = 55, steps.y = 210, steps.style.fontSize = 37;
    stepsArc.style.display = "inline", stepsArc.x = 10, stepsArc.y = 155, stepsArc.width = 90, stepsArc.height = 90;        
    stepsIcon.style.display = "inline", stepsIcon.x = 35, stepsIcon.y = 220, stepsIcon.width = 35, stepsIcon.height = 35;
  } 
  if (numOfStats.text === "4" && position1.text === "0") { //4 Stats
    steps.style.display = "inline", steps.x = 47, steps.y = 200, steps.style.fontSize = 30;       
    stepsArc.style.display = "inline", stepsArc.x = 12, stepsArc.y = 155, stepsArc.width = 70, stepsArc.height = 70;        
    stepsIcon.style.display = "inline", stepsIcon.x = 32, stepsIcon.y = 205, stepsIcon.width = 25, stepsIcon.height = 25; 
  }
  if (numOfStats.text === "5" && position1.text === "0" || numOfStats.text === "6" && position1.text === "0" || numOfStats.text === "7" && position1.text === "0") { //5 Stats
    steps.style.display = "inline", steps.x = 37, steps.y = 200, steps.style.fontSize = 30;       
    stepsArc.style.display = "inline", stepsArc.x = 2, stepsArc.y = 155, stepsArc.width = 70, stepsArc.height = 70;        
    stepsIcon.style.display = "inline", stepsIcon.x = 22, stepsIcon.y = 205, stepsIcon.width = 25, stepsIcon.height = 25; 
  }  

This code repeats if for position 2 through 7 with different xy coordinates.

This is then duplicated for 7 different stats.

 

What I would like to do set the xy coordinates as static and give it a name like "position1" and then be able call it. For example

if (numOfStats.text === 1 && position.text ===  0)

position1()  //sets the steps icon, arc and text style.display and xy coordinates

 

They problem that I run into, is how to generalize so that I don't need to call steps.style, steps.x/y, stepsArc.x/y etc.

Best Answer
0 Votes

Could you use an array of the values that differ between settings? If so, you could write a function that takes the setting value as an argument, reads the relevant entries from the array, and applies them.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

So, what I ended up doing was I created a function for the position array which would rename the element id to something generic name. Then I set up set up an if/else function for each possible xy value for each position using that generic name. Once the position was done, I renamed the element back to what it should be. 

 

var steps = document.getElementById("steps");
var numOfStats = document.getElementById("numOfStats"); //Array number count result\\
    
function setPosition() { 
  if (position1.text==="0") { //statArray first number is 0\\
    var stat = document.getElementById("steps"); 
    stat.style.display = "inline"; 
  }
    //**STEPS STAT IN POSITION 1**\\
    if (position1.text === "0" && numOfStats.text === "1") {
      setPosition1of1();
  } 
  var steps = document.getElementById("steps");
}

//POSITION 1\\
function setPosition1of1() {
      stat.style.display = "inline", stat.x = 150, stat.y = 235, stat.style.fontSize = 50;
}    

 

Best Answer
0 Votes