Javascript应用程序在大约两小时后冻结(内存泄漏?)

Javascript应用程序在大约两小时后冻结(内存泄漏?),javascript,html,memory-leaks,Javascript,Html,Memory Leaks,我目前正在开发一个家庭自动化用户界面,运行在墙上安装的android(版本4.2.2)平板电脑上,在几分钟的不活动后,它会显示一个“屏幕保护程序”html页面 正如您在上面的屏幕截图中所看到的,这个“屏幕保护程序”基本上由以下功能组成: 显示当前时间和日期的时钟,由脚本date_time.js触发,每隔一秒刷新一次 右上侧的图片,显示报警的当前状态 每3500毫秒随机重新定位一张图片“Touchez l’écran倾倒quitter le mode veille” 上面第2)点和第3)点都由另

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

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

  • 显示当前时间和日期的时钟,由脚本date_time.js触发,每隔一秒刷新一次
  • 右上侧的图片,显示报警的当前状态
  • 每3500毫秒随机重新定位一张图片“Touchez l’écran倾倒quitter le mode veille”
  • 上面第2)点和第3)点都由另一个脚本运行,该脚本存储在名为“screensaver_run.js”的脚本中。getAlarmDataFromDatabase方法正在从mysql数据库检索数据

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

    阅读了一些互联网上的文档,特别是,我已经实现了一些更改,比如将变量的声明从“var”更改为“let”

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

    此外,我在控制台上查询:

    • performance.memory.usedJSHeapSize并获得一些更改值: 3430886、3195206、4743246、3402767等

    • performance.memory.jsHeapSizeLimit和got:4294705152

    知道这款平板电脑的调试可能不如现代浏览器那么先进,有人知道从哪里开始调查吗?我的平板电脑“已经”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>
    
    
    Domoos |屏幕保护程序屏幕
    

    21度;C

    151è;我是安和埃库特的朋友;2020年。
    Bonsoir

    ECLARICIES

    我的javasript文件screensaver_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;
    }
    
    函数runScreenSaver()
    {
    设xmin=0;
    设xmax=890;
    设ymin=0;
    设ymax=430;
    让斯代特;
    让时光流逝;
    让Boverlapp获得授权;
    让b显示pos;
    让zRandomImage;
    让我们继续前进;
    让我们合作;
    让xCoordStr;
    让yCoordStr;
    Boverlap=true;
    b显示位置=假;
    //如果禁止重叠,x最小和y最小参数将被重新定义为略低于该线
    如果(!Boverlap授权)
    {
    xmin=15;
    ymin=130;
    }
    //根据最小值和最大值计算随机x和y
    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(“随机放置”);
    zRandomImage.style.left=xCoordStr;
    zRandomImage.style.top=yCoordStr;
    //而不是在“标记自由文本”中显示消息,
    //显示“randomPlacement”对象的随机定义坐标
    如果(b显示位置)
    {
    document.getElementById(“tag_free_text”).innerHTML='X:'+xCoordStr+'
    Y:'+yCoordStr; } document.getElementById(“日期”).innerhtml=getTimeDate(“日期”); getAlarmDataFromDatabase(); zRandomImage=null; xCoord=null; yCoord=null; xCoordStr=null; yCoordStr=null; setTimeout('runScreenSaver()','3500'); } 函数设置() { this.addEventListener(“mousemove”,exitScreenSaver,false); this.addEventListener(“mousedown”,exitScreenSaver,false); 此.addEventListener(“按键”,exitScreenSaver,false); 这个.addEventListener(“DOMMouseScroll”,exitScreenSaver,false); 此.addEventListener(“鼠标滚轮”,exitScreenSaver,false); 此.addEventListener(“touchstart”,exitScreenSaver,false); this.addEventListener(“MSPointerMove”,exitScreenSaver,false); } 函数getAlarmDataFromDatabase() { 让ajax=newXMLHttpRequest(); 设id_分量; 让技术人员命名html; 让comp_值; 让数据; open(“GET”,“php/data4screensaver1.php”,true); ajax.send(); ajax.onreadystatechange=函数() { if(this.readyState==4&&this.status==200) { data=JSON.parse(this.responseText); 对于(var a=0;afunction 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
    
    $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;
    }
    
    ?>