首页 > 解决方案 > Javascript 应用程序在大约两个小时后冻结(内存泄漏?)

问题描述

我目前正在开发一个家庭自动化用户界面,在壁挂式安卓(4.2.2 版)平板电脑上运行,几分钟不活动后,它会显示一个“屏幕保护程序”html 页面。

在此处输入图像描述

正如您在上面的屏幕截图中看到的,这个“屏幕保护程序”基本上包含以下功能:

  1. 显示当前时间和日期的时钟,由脚本 date_time.js 触发并以一秒间隔刷新;
  2. 右上角的图片显示警报的当前状态;
  3. 每 3500 毫秒随机重新定位的图片“Touchez l'écran pour quitter le mode veille”。

上面的 2) 和 3) 点都由存储在名为“screensaver_run.js”的脚本中的另一个脚本运行。getAlarmDataFromDatabase 方法正在从我的 mysql 数据库中检索数据。

现在,对于问题陈述:大约两个小时后,整个屏幕冻结(包括时钟和重新定位脚本),甚至平板电脑也无法 ping 通。我怀疑正在发生内存泄漏,但经过几个不眠之夜......和大量咖啡......我无法找出问题的根本原因。

阅读互联网上的一些文档,特别是https://www.lambdatest.com/blog/eradicating-memory-leaks-in-javascript,我已经实现了一些更改,例如将变量的声明从“var”更改为“让”。

在 Chrome 中,我在 2 1/2 分钟内运行脚本并分析了内存使用情况(我有可用的 heaptimeline 文件,如果它可以提供任何帮助,但在这里我不太确定如何分析它?):

在此处输入图像描述

此外,我向控制台查询:

有没有人知道从哪里开始调查,知道这款平板电脑的调试可能性不如现代浏览器先进?我的平板电脑“已经”使用 5 年了......升级这款平板电脑不是一种选择。

非常感谢您花时间阅读我,我希望我的帖子是可以理解的,有据可查的,并且在未来,可以帮助其他人度过一个安宁的夜晚:)

我的html页面的代码(以'screen_saver.html命名)如下:

<!DOCTYPE html>
<html>
  <head>
    <title>Domoos | Screen saver screen</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
    <meta http-equiv="pragma" content="no-cache">
    <link rel="shortcut icon" href="favicon.ico">
    <link rel="stylesheet" type="text/css" href="css/mystyle_saver.css?rnd=999" />
    <script type="text/javascript" src="scripts/date_time.js"></script>
    <script type="text/javascript" src="scripts/screensaver_run.js"></script>
  </head>
  <body onload="runScreenSaver(); setup();">
    <div style="position:absolute" id="randomPlacement">
      <p><img src="assets/pictures/texte_sortie_veille.png" alt ="" style="width:90px;height:90px;" border="0"></p>
    </div>
    <div id="svg">
      <svg height="210" width="1020">
        <line x1="11" y1="100" x2="1015" y2="100" style="stroke:rgb(69,69,66);stroke-width:3" />
      </svg>
    </div>
    <div id="date"></div>
    <div id="time"></div>
    <div id="icon_alarm">
      <img id="img_alarm" src="assets/icons/alarme_eteinte.png" alt ="" style="width:27px;height:35px;">
    </div>
    <div id="tag_temperature">
      <p>21&deg;C</p>
    </div>
    <div id="tag_free_text">
      <p>151<sup>&egrave;me</sup> jour de l'ann&eacute;e 2020.<br>Bonsoir</p>
    </div>
    <div id="meteo_icon">
      <img src="assets/meteo_icons/eclaircies-big.png" alt="" style="width:40px;height:40px;">
    </div>
    <div id="tag_weather_condition">
      <p>Eclaircies</p>
    </div>
  </body>
</html>

我的 javasript 文件 screenaver_run.js 的代码:

function runScreenSaver()
{
  let xmin = 0;
  let xmax = 890;
  let ymin = 0;
  let ymax = 430;
  let sDate;
  let sTime;
  let bOverlapAuthorised;
  let bDisplayPos;
  let zRandomImage;
  let xCoord;
  let yCoord;
  let xCoordStr;
  let yCoordStr;

  bOverlapAuthorised = true;
  bDisplayPos = false;

  // If overlap is forbidden, the x min and y min parameters will be redefined to be slightly below the line
  if (!bOverlapAuthorised)
  {
    xmin = 15;
    ymin = 130;
  }

  // Computes a random x and y, based on the min and ma
  xCoord = Math.floor((Math.random()*xmax)+xmin);
  yCoord = Math.floor((Math.random()*ymax)+ymin);

  xCoordStr = xCoord.toString() + "px";
  yCoordStr = yCoord.toString() + "px";

  zRandomImage = document.getElementById("randomPlacement");
  zRandomImage.style.left = xCoordStr;
  zRandomImage.style.top = yCoordStr;

  // Instead of displaying a message in the 'tag_free_text',
  // shows the randomly defined coordinates of the 'randomPlacement' object
  if (bDisplayPos)
  {
    document.getElementById("tag_free_text").innerHTML = 'X:' + xCoordStr + '<br>Y:' + yCoordStr;
  }

  document.getElementById("date").innerhtml=getTimeDate('date');

  getAlarmDataFromDatabase();

  zRandomImage = null;
  xCoord = null;
  yCoord = null;
  xCoordStr = null;
  yCoordStr = null;
  setTimeout('runScreenSaver()','3500');
}

function setup()
{
  this.addEventListener("mousemove", exitScreenSaver, false);
  this.addEventListener("mousedown", exitScreenSaver, false);
  this.addEventListener("keypress", exitScreenSaver, false);
  this.addEventListener("DOMMouseScroll", exitScreenSaver, false);
  this.addEventListener("mousewheel", exitScreenSaver, false);
  this.addEventListener("touchstart", exitScreenSaver, false);
  this.addEventListener("MSPointerMove", exitScreenSaver, false);
}

function getAlarmDataFromDatabase()
{
  let ajax = new XMLHttpRequest();
  let id_component;
  let technical_name_html;
  let comp_value;
  let data;

  ajax.open("GET", "php/data4screensaver1.php", true);
  ajax.send();
  ajax.onreadystatechange = function() 
  {
    if (this.readyState == 4 && this.status == 200) 
    {
      data = JSON.parse(this.responseText);

      for(var a = 0; a < data.length; a++) 
      {
        id_component = data[a]['id_component'];
        technical_name_html = data[a]['technical_name_html'];
        comp_value = parseInt(data[a]['value']);
      }

      data = null;

      console.log("ID Component: " + id_component);
      //console.log("Valeur de l'alarme : " + comp_value);

      switch (comp_value) 
      {
        case 0:
        case 50:
        case 100:
          displayPictureAlarm(comp_value);
          break;

        default:
          displayPictureAlarm(-1);
          break;
      }
    }
  };

  ajax = null;
  id_component = null;
  technical_name_html = null;
  comp_value = null;
}

function exitScreenSaver(e)
{
  goActive(e);
}

function goActive(event)
{
  // do something
  console.log(".. active ..");
  //event.preventDefault();

  this.removeEventListener("mousemove", exitScreenSaver);
  this.removeEventListener("mousedown", exitScreenSaver);
  this.removeEventListener("keypress", exitScreenSaver);
  this.removeEventListener("DOMMouseScroll", exitScreenSaver);
  this.removeEventListener("mousewheel", exitScreenSaver);
  this.removeEventListener("touchstart", exitScreenSaver);
  this.removeEventListener("MSPointerMove", exitScreenSaver);

  window.open("index.html","_self");
}


function displayPictureAlarm(pValue)
{
  let z;

  z = document.getElementById("img_alarm");

  if (pValue == 0) // désarmée
  {
    z.src = "assets/icons/alarme_desarmee.png";
  }

  if (pValue == 50) // partielle
  {
    z.src = "assets/icons/alarme_partielle.png";
  }

  if (pValue == 100) // totale
  {
    z.src = "assets/icons/alarme_totale.png";
  }

  if (pValue == -1) // éteinte
  {
    z.src = "assets/icons/alarme_eteinte.png";
  }

  z = null;
}

我的 javascript 文件 datetime.js 的代码(在上面的方法 runScreenSaver 中调用):

function getDate(id)
{
  date = new Date;
  year = date.getFullYear();
  month = date.getMonth();
  month += 1;        
  d = date.getDate();
  day = date.getDay();
  days = new Array('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi');

  if (d<10)
  {
    d = "0"+d;
  }
  if(month<10)
  {
    month = "0"+month;
  }

  result = ''+days[day]+' '+d+'.'+month+'.'+year;
  result = days[day]+' '+d+'.'+month+'.'+year;
  document.getElementById(id).innerHTML = result;
  setTimeout('getDate("'+id+'");','1000');

  return true;
}

function getTimeDateMainScreen()
{
  var za;
  var zb;
  var zc;
  var mydate;
  var result1;
  var result2;
  var result3;

  mydate = new Date;
  year = mydate.getFullYear();
  month = mydate.getMonth();
  day = mydate.getDate();
  weekday = mydate.getDay();
  hrs = mydate.getHours();
  mns = mydate.getMinutes();
  secs = mydate.getSeconds();

  days = new Array('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi');

  month += 1;

  if (day < 10)
  {
    day = "0" + day;
  }

  if(month < 10)
  {
    month = "0" + month;
  }

  if(hrs < 10)
  {
    hrs = "0" + hrs;
  }
  if(mns < 10)
  {
    mns = "0" + mns;
  }
  if(secs < 10)
  {
    secs = "0" + secs;
  }

  //result = ''+days[weekday]+' '+d+'.'+month+'.'+year;
  //result = days[weekday]+' '+d+'.'+month+'.'+year;
  result1 = day + "." + month + "." + year;
  result2 = days[weekday];
  result3 = hrs + ":" + mns + ":" + secs;

  za = document.getElementById("curr_date");
  zb = document.getElementById("curr_weekday");
  zc = document.getElementById("curr_time");

  za.innerHTML = result1;
  zb.innerHTML = result2;
  zc.innerHTML = result3;

  za = null;
  zb = null;
  zc = null;
  mydate = null;
  result1 = null;
  result2 = null;
  result3 = null;

  setTimeout('getTimeDateMainScreen();','500');
}

function getTime(id)
{
  date = new Date;

  h = date.getHours();

  if(h<10)
  {
          h = "0"+h;
  }
  m = date.getMinutes();
  if(m<10)
  {
          m = "0"+m;
  }
  s = date.getSeconds();
  if(s<10)
  {
    s = "0"+s;
  }
  result = ''+h+':'+m+':'+s;
  document.getElementById(id).innerHTML = result;
  setTimeout('getTime("'+id+'");','1000');

  return true;
}

function getTime2()
{
  date = new Date;

  h = date.getHours();

  if(h<10)
  {
          h = "0"+h;
  }
  m = date.getMinutes();
  if(m<10)
  {
          m = "0"+m;
  }
  s = date.getSeconds();
  if(s<10)
  {
    s = "0"+s;
  }
  result = ''+h+':'+m+':'+s;
  document.getElementById("time").innerHTML = result;
  setTimeout('getTime2();','1000');
}

function getTimeDate(id)
{
  let date;
  let year;
  let month;
  let d;
  let day;
  let days;
  let h;
  let m;
  let s;
  let result;

  date = new Date;
  console.log("J'affiche la date3");
  year = date.getFullYear();
  month = date.getMonth();
  month += 1;
  d = date.getDate();
  day = date.getDay();
  days = new Array('Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi');
  h = date.getHours();
  m = date.getMinutes();
  s = date.getSeconds();


  if (d<10)
  {
    d = "0"+d;
  }

  if(month<10)
  {
    month = "0"+month;
  }

  if(h<10)
  {
    h = "0"+h;
  }

  if(m<10)
  {
    m = "0"+m;
  }

  if(s<10)
  {
    s = "0"+s;
  }

  result = ''+days[day]+' '+d+'.'+month+'.'+year +' ' + h+':'+m+':'+s;
  document.getElementById(id).innerHTML = result;

  date = null;
  year = null;
  month = null;
  d = null;
  day = null;
  days = null;
  h = null;
  m = null;
  s = null;
  result = null;

  setTimeout('getTimeDate("'+id+'");','1000');
  return true;   

 }

最后,这是我的 php (data4screensaver1.php) 从我的 mysql 数据库中检索数据:

<?php

$host = "ip_Address_db";
$db_user_encoded = "user_encoded";
$db_password_encoded = "pw_encoded";
$db_name_encoded = "db_name_encoded";

$conn = mysqli_connect($host, (encrypt_decrypt('decrypt', $db_user_encoded)), (encrypt_decrypt('decrypt', $db_password_encoded)), (encrypt_decrypt('decrypt', $db_name_encoded )));
$result = mysqli_query($conn, "CALL sp_tbl_domotique_components_get_lab61()");

$data = array();
while ($row = mysqli_fetch_object($result))
{
    array_push($data, $row);
}

echo json_encode($data);
exit();


function encrypt_decrypt($action, $string) 
{
    $output = false;
    $encrypt_method = "AES-256-CBC";
    $secret_key = '$SecretKey$';
    $secret_iv = '$SecretIV$';
    // hash
    $key = hash('sha256', $secret_key);

    // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
    $iv = substr(hash('sha256', $secret_iv), 0, 16);
    if ( $action == 'encrypt' ) {
        $output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
        $output = base64_encode($output);
    } else if( $action == 'decrypt' ) {
        $output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
    }
    return $output;
}

?>

标签: javascripthtmlmemory-leaks

解决方案


推荐阅读