Сохранение файла .docx или .ppt локально с использованием getFileAsync (fileType, options, callback)

Сбор мусора в Java выполняется на основе «достижимости». JLS определяет этот термин следующим образом:

«Доступаемый объект - это любой объект, к которому можно получить доступ в любом потенциальном продолжающемся вычислении из любой живой нити».

Пока объект доступен *, он не подходит для сбора мусора.

JLS оставляет его до реализации Java, чтобы выяснить, как определить, является ли объект может быть доступен . Если реализация не может быть уверенной, она свободна рассматривать теоретически недостижимый объект как достижимый ... и не собирать его. (Действительно, JLS позволяет реализации не собирать ничего, никогда! Никакая разумная реализация не сделает этого.)

На практике (консервативная) достижимость вычисляется путем трассировки; глядя на то, что может быть достигнуто следующими ссылками, начиная с переменных класса (статических) и локальных переменных в потоковых стеках.


Вот что это значит для вашего вопроса:

Если я вызываю: myTree = null;, что действительно происходит с связанными объектами TreeNode внутри дерева? Будет ли собран мусор, или я должен установить null все связанные объекты внутри древовидного объекта ??

Предположим, что myTree содержит последнюю оставшуюся доступную ссылку на корень дерева .

  1. Ничего не произойдет немедленно.
  2. Если внутренние узлы ранее были доступны только через корневой узел, тогда они теперь недоступны и имеют право на сбор мусора. (В этом случае назначение null ссылок на внутренние узлы не требуется.)
  3. Однако, если внутренние узлы достижимы с помощью других путей, они предположительно все еще достижимы, и поэтому НЕ имеет права на сбор мусора. (В этом случае ошибка присваивания null для ссылок на внутренние узлы является ошибкой. Вы разбираете структуру данных, которую что-то еще может попытаться использовать.)

Если myTree не содержит оставшуюся оставшуюся ссылку на корень дерева, тогда обнуление внутренней ссылки является ошибкой по той же причине, что и в 3. выше.


Итак, когда должен вы null вещи, чтобы помочь сборщику мусора?

Случаи, когда вам нужно беспокоиться, когда вы можете что ссылка в некоторой ячейке (локальная, экземпляр или переменная класса или элемент массива) больше не будет использоваться, но компилятор и среда выполнения не могут! Случаи делятся примерно на три категории:

  1. Ссылки на объекты в переменных класса ... которые (по определению) никогда не выходят за рамки.
  2. Ссылки на объекты в локальных переменных, которые все еще в области ... но не будут использоваться. Например:
     public List<Pig> pigSquadron(boolean pigsMightFly) {
       List<Pig> airbornePigs = new ArrayList<Pig>();
       while (...) {
         Pig piggy = new Pig();
         ...
         if (pigsMightFly) {
           airbornePigs.add(piggy);
         }
         ...
       }
       return airbornePigs.size() > 0 ? airbornePigs : null;
     }
    
    В приведенном выше сообщении мы знаем, что если pigsMightFly является ложным, то объект списка не будет использоваться. Но никакой основной компилятор Java не может рассчитывать на это.
  3. Ссылки на объекты в переменных экземпляра или в ячейках массива, где инварианты структуры данных означают, что они не будут использоваться. Пример экземпляра @ edalorzo - пример этого.

Следует отметить, что компилятор / среда выполнения иногда может определить, что переменная в области видимости эффективно мертва. Например:

public void method(...) {
    Object o = ...
    Object p = ...
    while (...) {
        // Do things to 'o' and 'p'
    }
    // No further references to 'o'
    // Do lots more things to 'p'
}

Некоторые компиляторы Java / runtimes могут распознавать, что «o» не требуется после окончания цикла и обрабатывает переменную как мертвую.


* На самом деле речь идет о сильной достижимости. Модель достижимости GC более сложна, если вы рассматриваете мягкие, слабые и фантомные ссылки. Однако они не имеют отношения к случаю использования ОП.

0
задан Tobias Thornfeldt Nissen 18 January 2019 в 09:40
поделиться

1 ответ

Мне удалось решить проблему сразу после публикации вопроса. Исправление состояло в том, чтобы создать новый UInt8Array, а затем создать новый BLOB-объект из этого UInt8Array. По сути, это означает, что последний метод становится:

public onGotAllSlices(docdataSlices) {
    let docdata = [];
    for (let i = 0; i < docdataSlices.length; i++) {
      docdata = docdata.concat(docdataSlices[i]);
    }

    const byteArray = new Uint8Array(docdata);

    const blob = new Blob([byteArray]);

    const a = document.createElement('a');
    url = URL.createObjectURL(blob);
    a.href = url;
    a.download = 'WordTest.docx';
    document.body.appendChild(a);
    a.click();
    setTimeout(function() {
      document.body.removeChild(a);
      window.URL.revokeObjectURL(url);
    }, 0);
}
0
ответ дан Tobias Thornfeldt Nissen 18 January 2019 в 09:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: