Утечка памяти при объединении больших двоичных объектов в более крупные, но не знаю, почему

Этот код немного странный на данный момент, потому что он нарезает медиафайл на части, считывает каждую часть как буфер массива, собирает результаты и загружает их в элемент видео; но это тест перед заменой функции fetch_video данными, подаваемыми откуда-то еще.

Мой вопрос: почему утекает память? URL-адрес объекта отменяется при нажатии кнопки. Некоторые переменные являются глобальными, но не будут таковыми, если в конечном итоге будет использован этот метод.

Когда файл открывается в средстве выбора файлов и обрабатывается, оперативная память, конечно, увеличивается, но после этого полностью не освобождается. Я пытался повторно открыть видеофайл размером 100 МБ. Каждый раз потребление оперативной памяти увеличивается примерно на 300 МБ, а после нажатия кнопки отзыва URL-адреса объекта объем оперативной памяти уменьшается примерно на 100 МБ. Таким образом, каждая итерация потребляет еще 200 МБ, которые не освобождаются. Я попытался установить для всех переменных значение null при закрытии каждой функции на случай, если некоторые ссылки были сохранены, но это не имело значения.

Не могли бы вы сказать мне, что я делаю неправильно, пожалуйста? Спасибо.

      <body>
  <video controls></video>
  <label><input type="file"></input>Hard Drive</label>
  <button>Revoke Blob URL</button>
</body>


  "use strict";

  var video_file, blob_url,
      video_blob = new Array(),
      chunk = 1024 * 1024, 
      video = document.body.firstElementChild;

  video.nextElementSibling.addEventListener( 'change', open_file, false );
  video.addEventListener( 'canplay', () => { console.log( "Video can play." ); }, false );
  video.nextElementSibling.nextElementSibling.addEventListener( 'mousedown', () =>
    {
      video.removeAttribute( "src" );
      video.load();
      URL.revokeObjectURL( blob_url );
      video_file = null;
    }, false );
    
function open_file( evt )
 {
  video_file = evt.target.files[0]; 
  fetch_video.remaining = video_file.size;
  fetch_video.start = 0;
  append_blobs();
 } // close open_file
    
async function append_blobs()
 {
  var buf;
  if ( fetch_video.remaining > 0 )
    {
      buf = await fetch_video();
      if ( buf !== -1 )
        {
            video_blob.push( buf );
          append_blobs();
        }
      else 
        console.log( "error" );
    }
  else
    {
      let v = new Blob( video_blob, { type : video_file.type } );
      blob_url = URL.createObjectURL( v );
      video.src = blob_url;
      v = null;
    };
}
    
function fetch_video()
 {
  return new Promise( ( resolve, reject ) =>
   {
    let f = fetch_video;
    f.end = f.start + Math.min( f.remaining, chunk );
    console.log( "start: " + f.start + ", end: " + f.end + ", remaining: " + f.remaining + ", end - start: " + ( f.end - f.start ) );
    if ( f.remaining > 0 )
        read_chunk( new Blob( [ video_file.slice( f.start, f.end ) ], { type : video_file.type } ) )  
          .then( ( data ) => 
                    {
                      f.remaining = video_file.size - f.end;
                      f.start = f.end;
                      resolve( data );
                    },
                 ( err ) => { reject( -1 ); }
                 );
    else
      reject( - 1 );
  });
 } // close fetch_video

function read_chunk( blob )
  {          
    return new Promise( ( resolve, reject ) =>
      {
        let reader = new FileReader();
        reader.onload = () => { resolve( reader.result ); }; 
        reader.onerror = ( e ) => { reject(); };
        reader.readAsArrayBuffer( blob );
      }); // close new promise
  } // close read_file

0 ответов

Другие вопросы по тегам