【问题标题】:JavaScript Memory leak using setInterval使用 setInterval 的 JavaScript 内存泄漏
【发布时间】:2026-01-06 04:10:02
【问题描述】:

我的 javascript 应用程序泄漏内存时遇到问题。我在网上查了一些东西,我似乎已经通过使用

关闭了 setInterval 循环中的任何内存分配
variableX = null

技术。但是应用程序仍然以某种方式泄漏内存,谁能指出可能导致这种泄漏的原因?这是我的代码:

<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
  <meta charset="utf-8">
  <title>Simple markers</title>
  <style>
     html, body, #map-canvas {
     height: 100%;
     margin: 0px;
     padding: 0px
     }
  </style>
  <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
  <script>

     function initialize() {
         var myLatlng = new google.maps.LatLng(43.46949, -80.54661);
         var lat = 0;
         var long = 0;
         var mapOptions = {
             zoom: 16,
             center: myLatlng,
             mapTypeId: google.maps.MapTypeId.ROADMAP
         }

         function loadXMLDoc() {
             var xhr;
             if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
                 xhr = new XMLHttpRequest();
             } else { // code for IE6, IE5
                 xhr = new ActiveXObject("Microsoft.XMLHTTP");
             }
             xhr.open("GET", "coordinates.txt", true);
             xhr.onreadystatechange = function () {
                 if (this.readyState == 4) {
                     var textfileString = this.responseText;
                     var longLatString = textfileString.split(',');
                     lat = parseFloat(longLatString[0])
                     long = parseFloat(longLatString[1])
                     textfileString = null
                     longLatString = null
                 }
             }
             xhr.send();
             xhr = null
         }
         var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
         var marker = new google.maps.Marker({
             position: myLatlng,
             map: map,
             title: 'Hello World!'
         });
         setInterval(function () {
             loadXMLDoc()
             var newLatLng = new google.maps.LatLng(lat, long);
             marker.setPosition(newLatLng);
             newLatLng = null
         }, 16);
     }
     google.maps.event.addDomListener(window, 'load', initialize);

  </script>
</head>
<body>
  <div id="map-canvas"></div>
</body>
</html>

【问题讨论】:

  • 内存泄漏的证据是什么?
  • 在我的应用程序的浏览器中运行它,当应用程序继续运行时,它会在任务管理器中显示内存不断增加,如果离开很长时间,程序最终会崩溃。
  • 等等...你每 16 毫秒发出一个新的 XHR 请求?
  • 我正在使用 Webkit 浏览器来浏览 C# winforms:webkitdotnet.sourceforge.net
  • ...仅供参考,当var newLatLng = new google.maps... 运行时,您的latlong 将不会从XHR 请求中收到

标签: javascript ajax memory memory-leaks


【解决方案1】:

您正在发送新的XMLHttpRequest,而无需等待旧的完成。如果响应的接收时间超过 16 毫秒(很可能会这样),“请求队列”将会增长,从而导致内存泄漏。

发送请求不间断是个坏主意。如果您需要恒定的坐标流,请将多个坐标打包到一个响应中,并仅在前一个完成后发送新请求:

function getCoordinates() {
    ...
    xhr.onreadystatechange = function() {
        ...
        setTimeout(getCoordinates, 30000);
    }
}

更好的是,使用 Websockets。

【讨论】:

  • 澄清setTimeout 应该在readystate==4 条件后面可能不是一个坏主意。不过,您确实在第一句话中暗示了这一点。
  • 我认为 16 毫秒足以处理大多数请求,因为它只是从本地文件中提取信息?这样做也违背了应用程序的目的,它应该更新用户实时发送的 gps 坐标,在这个应用程序中延迟 30 秒的位置更新是不可接受的。
  • @user1296932:然后使用 Websockets。 HTTP 请求不是“实时的”。