• <small id='O8QGt'></small><noframes id='O8QGt'>

    1. <legend id='O8QGt'><style id='O8QGt'><dir id='O8QGt'><q id='O8QGt'></q></dir></style></legend><tfoot id='O8QGt'></tfoot>

        • <bdo id='O8QGt'></bdo><ul id='O8QGt'></ul>
        <i id='O8QGt'><tr id='O8QGt'><dt id='O8QGt'><q id='O8QGt'><span id='O8QGt'><b id='O8QGt'><form id='O8QGt'><ins id='O8QGt'></ins><ul id='O8QGt'></ul><sub id='O8QGt'></sub></form><legend id='O8QGt'></legend><bdo id='O8QGt'><pre id='O8QGt'><center id='O8QGt'></center></pre></bdo></b><th id='O8QGt'></th></span></q></dt></tr></i><div id='O8QGt'><tfoot id='O8QGt'></tfoot><dl id='O8QGt'><fieldset id='O8QGt'></fieldset></dl></div>

        使用 Data URI 快速更新图像会导致缓存、内存泄漏

        Rapidly updating image with Data URI causes caching, memory leak(使用 Data URI 快速更新图像会导致缓存、内存泄漏)

            <bdo id='96ikp'></bdo><ul id='96ikp'></ul>

            • <legend id='96ikp'><style id='96ikp'><dir id='96ikp'><q id='96ikp'></q></dir></style></legend>
            • <i id='96ikp'><tr id='96ikp'><dt id='96ikp'><q id='96ikp'><span id='96ikp'><b id='96ikp'><form id='96ikp'><ins id='96ikp'></ins><ul id='96ikp'></ul><sub id='96ikp'></sub></form><legend id='96ikp'></legend><bdo id='96ikp'><pre id='96ikp'><center id='96ikp'></center></pre></bdo></b><th id='96ikp'></th></span></q></dt></tr></i><div id='96ikp'><tfoot id='96ikp'></tfoot><dl id='96ikp'><fieldset id='96ikp'></fieldset></dl></div>

                  <tbody id='96ikp'></tbody>

                <small id='96ikp'></small><noframes id='96ikp'>

                  <tfoot id='96ikp'></tfoot>
                  本文介绍了使用 Data URI 快速更新图像会导致缓存、内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  I have a webpage that rapidly streams JSON from the server and displays bits of it, about 10 times/second. One part is a base64-encoded PNG image. I've found a few different ways to display the image, but all of them cause unbounded memory usage. It rises from 50mb to 2gb within minutes. Happens with Chrome, Safari, and Firefox. Haven't tried IE.

                  I discovered the memory usage first by looking at Activity Monitor.app -- the Google Chrome Renderer process continuously eats memory. Then, I looked at Chrome's Resource inspector (View > Developer > Developer Tools, Resources), and I saw that it was caching the images. Every time I changed the img src, or created a new Image() and set its src, Chrome cached it. I can only imagine the other browsers are doing the same.

                  Is there any way to control this caching? Can I turn it off, or do something sneaky so it never happens?

                  Edit: I'd like to be able to use the technique in Safari/Mobile Safari. Also, I'm open to other methods of rapidly refreshing an image if anyone has any ideas.

                  Here are the methods I've tried. Each one resides in a function that gets called on AJAX completion.

                  Method 1 - Directly set the src attribute on an img tag

                  Fast. Displays nicely. Leaks like crazy.

                  $('#placeholder_img').attr('src', 'data:image/png;base64,' + imgString);
                  

                  Method 2 - Replace img with a canvas, and use drawImage

                  Displays fine, but still leaks.

                  var canvas = document.getElementById("placeholder_canvas");
                  var ctx = canvas.getContext("2d");
                  var img = new Image();
                  img.onload = function() {
                      ctx.drawImage(img, 0, 0); 
                  }   
                  img.src = "data:image/png;base64," + imgString;
                  

                  Method 3 - Convert to binary and replace canvas contents

                  I'm doing something wrong here -- the images display small and look like random noise. This method uses a controlled amount of memory (grows to 100mb and stops), but it is slow, especially in Safari (~50% CPU usage there, 17% in Chrome). The idea came from this similar SO question: Data URI leak in Safari (was: Memory Leak with HTML5 canvas)

                  var img = atob(imgString);
                  var binimg = [];
                  for(var i = 0; i < img.length; i++) {
                      binimg.push(img.charCodeAt(i));
                  }
                  var bytearray = new Uint8Array(binimg);
                  
                  // Grab the existing image from canvas
                  var ctx = document.getElementById("placeholder_canvas").getContext("2d");
                  var width = ctx.canvas.width, 
                      height = ctx.canvas.height;
                  var imgdata = ctx.getImageData(0, 0, width, height);
                  
                  // Overwrite it with new data
                  for(var i = 8, len = imgdata.data.length; i < len; i++) {
                      imgdata.data[i-8] = bytearray[i];
                  }
                  
                  // Write it back
                  ctx.putImageData(imgdata, 0, 0);
                  

                  解决方案

                  I know it's been years since this issue was posted, but the problem still exists in recent versions of Safari Browser. So I have a definitive solution that works in all browsers, and I think this could save jobs or lives!.

                  Copy the following code somewhere in your html page:

                  // Methods to address the memory leaks problems in Safari
                  var BASE64_MARKER = ';base64,';
                  var temporaryImage;
                  var objectURL = window.URL || window.webkitURL;
                  
                  function convertDataURIToBlob(dataURI) {
                      // Validate input data
                      if(!dataURI) return;
                  
                      // Convert image (in base64) to binary data
                      var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
                      var base64 = dataURI.substring(base64Index);
                      var raw = window.atob(base64);
                      var rawLength = raw.length;
                      var array = new Uint8Array(new ArrayBuffer(rawLength));
                  
                      for(i = 0; i < rawLength; i++) {
                          array[i] = raw.charCodeAt(i);
                      }
                  
                      // Create and return a new blob object using binary data
                      return new Blob([array], {type: "image/jpeg"});
                  }
                  

                  Then when you receive a new frame/image base64Image in base64 format (e.g. data:image/jpeg;base64, LzlqLzRBQ...) and you want to update a html <img /> object imageElement, then use this code:

                  // Destroy old image
                  if(temporaryImage) objectURL.revokeObjectURL(temporaryImage);
                  
                  // Create a new image from binary data
                  var imageDataBlob = convertDataURIToBlob(base64Image);
                  
                  // Create a new object URL object
                  temporaryImage = objectURL.createObjectURL(imageDataBlob);
                  
                  // Set the new image
                  imageElement.src = temporaryImage;
                  

                  Repeat this last code as much as needed and no memory leaks will appear. This solution doesn't require the use of the canvas element, but you can adapt the code to make it work.

                  这篇关于使用 Data URI 快速更新图像会导致缓存、内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  How to make rooftext effect and valley text effect in HTML5 (or Fabric.js)(如何在 HTML5(或 Fabric.js)中制作屋顶文字效果和山谷文字效果)
                  Draw border around nontransparent part of image on canvas(在画布上的图像不透明部分周围绘制边框)
                  dragging and resizing an image on html5 canvas(在 html5 画布上拖动图像并调整其大小)
                  What#39;s the difference between a boolean as primitive and a boolean as property of an object?(作为原始对象的布尔值和作为对象属性的布尔值有什么区别?)
                  I want to do animation of an object along a particular path(我想沿特定路径对对象进行动画处理)
                  How to upload image into HTML5 canvas(如何将图像上传到 HTML5 画布中)
                  1. <i id='JOgRf'><tr id='JOgRf'><dt id='JOgRf'><q id='JOgRf'><span id='JOgRf'><b id='JOgRf'><form id='JOgRf'><ins id='JOgRf'></ins><ul id='JOgRf'></ul><sub id='JOgRf'></sub></form><legend id='JOgRf'></legend><bdo id='JOgRf'><pre id='JOgRf'><center id='JOgRf'></center></pre></bdo></b><th id='JOgRf'></th></span></q></dt></tr></i><div id='JOgRf'><tfoot id='JOgRf'></tfoot><dl id='JOgRf'><fieldset id='JOgRf'></fieldset></dl></div>
                    • <bdo id='JOgRf'></bdo><ul id='JOgRf'></ul>
                          <tbody id='JOgRf'></tbody>

                        <small id='JOgRf'></small><noframes id='JOgRf'>

                        • <legend id='JOgRf'><style id='JOgRf'><dir id='JOgRf'><q id='JOgRf'></q></dir></style></legend>
                          <tfoot id='JOgRf'></tfoot>