2017-02-07 10 views
2

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

Я проверил это предположение со следующим кодом:

Observable.interval(1.microsecond).map(_ => System.currentTimeMillis) 
    .subscribe(x =>()) 

И действительно использование памяти неуклонно растет в течение всего 10-минутного периода в то время как приложение было работать.


Мой вопрос, если это возможно, чтобы создать экземпляр специальный Observable без кэша или, может быть, поручить это ограничить его кэш на каком-то уровне?

+2

Вы уверены, что в какой-то момент это не будет GC'd? – Carcigenicate

+0

@Carcigenicate 10 минут кажется довольно достаточным интервалом для GC, чтобы сделать это. Кроме того, логический кеш не должен быть GC'd, поскольку он хранит все значения и не разыменовывается, пока активен «Наблюдаемый». – Anton

+0

Тем не менее, открытие VisualVM и принудительное использование GC могут стоить попробовать. Я не знаю особенностей того, как работает «Наблюдаемый», но я знаю, что у меня были некоторые программы, которые держались на объектах, казалось бы, навсегда, только для того, чтобы быть автоматически очищенными, как только использование получило достаточно высокий уровень. – Carcigenicate

ответ

6

Только определенный набор Observables (например, ReplaySubject, replay(), GroupedObservable) имеют тенденцию кэшировать элементы, но не Observable.interval().

Что вы, вероятно, испытываете здесь, это сотни тысяч коробочных длинных значений. Если у вас много оперативной памяти, GC может не ударить, а просто увеличивать размер кучи до максимума. Предполагая, что вы действительно можете получить таймер 1 микросекунды, у вас есть скорость передачи данных 24 МБ/с или 1,4 ГБ/мин. Если вы останетесь один на 10 минут, вы, скорее всего, увидите форму пилообразной формы в памяти.