Утечка памяти из-за File.openRead и Streamhandling?

Я попал в утечку памяти. Я написал следующий пример, который постоянно увеличивает использование памяти:

import 'dart:io';
import 'dart:async';
import 'dart:utf';

Future<Stream<List<int>>> readFile2Stream(String path){
  File f = new File(path);
  return f.exists().then((bool exists){
    if( !exists ){
      return new Stream<List<int>>.fromIterable([encodeUtf8("Could not find $path")]); 
    }else{
      return f.openRead();
    }
  });
}

void readFile(String path){
  readFile2Stream(path).then(
    (Stream<List<int>> data){
      data.listen((List<int> data){
        print(data);
      },
      onError: (dynamic error){
        print("Error: $error");
      },
      onDone: (){
        print("Done");
      });
    }
  );
}

void main() {
  Timer t = new Timer.periodic(new Duration(seconds:2),(Timer it){
    readFile("memleaktest.dart");
  });
}

Может кто-нибудь дать мне подсказку по какой-то причине? Понятия не имею:-(

Небольшой дополнительный вопрос:

Есть ли способ упростить этот пример, избавившись от будущей инкапсуляции возвращаемых типов? Я не хочу использовать File.existsSync(), вместо этого я хочу добавить обработку Future к обработке Stream.

1 ответ

Решение

Нет утечки памяти. Сборщик мусора просто не работает, что является разницей.

Если вы сократите продолжительность (например, на 2 миллисекунды), вы увидите, что использование вашей памяти увеличивается, пока не достигнет определенной точки (500 МБ на моей машине, но ваш пробег может отличаться). По-видимому, в этот момент сборщик мусора запускается и освобождает неиспользуемую память, сокращая использование памяти практически до нуля. Потом опять поднимается и тд и тп

Что касается того, почему сборщик мусора не работает, я действительно не знаю. Кажется, нет никакой спецификации или документации, как работает GC.

По крайней мере, ваша память не теряется и будет переработана, если это необходимо. Итак, ваш код в порядке.

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