Утечка памяти из-за 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.
По крайней мере, ваша память не теряется и будет переработана, если это необходимо. Итак, ваш код в порядке.