Статьи

JavaFX Совет 23: экономьте память!

Свойства и привязки свойств, представленные в Java 8, являются чрезвычайно полезными концепциями программирования. Они особенно полезны при разработке пользовательских интерфейсов. На самом деле они настолько полезны, что разработчики стали жертвами идеи, что все должно быть собственностью, а не примитивом. К сожалению, они легко забывают, что такие свойства, как SimpleLongProperty, являются объектами гораздо большего размера, чем стандартные типы, такие как Long . И, конечно, они намного больше, чем примитивные типы данных, такие как long .

В одном из моих текущих проектов почти каждый объект модели, используемый клиентом, состоит из свойств. Для многих из этих объектов модели это правильный подход, потому что они будут редактироваться / изменяться через элементы управления JavaFX. Но есть также много модельных объектов, которые не редактируются. Они существуют для поддержки рендеринга расписаний в элементе управления FlexGanttFX . Эти объекты не нужно наблюдать, следовательно, они не должны предоставлять свойства … но они делают, и они тратят много памяти, потому что они делают.

Одним из способов решения этой проблемы является рефакторинг классов модели и избавление от всех свойств, но с другой стороны, мы можем захотеть использовать эти объекты в будущем выпуске в другом контексте, а затем нам могут понадобиться свойства, потому что мы хотим их редактировать. непосредственно. Что делать?

Теневые Поля

Решение этой проблемы — то, что я недавно видел, как Геррит Грюнвальд делал в коде своего проекта Medusa, и шаблон, который был описан самим г-ном Пропертисом Майклом Хайнрихсом . Шаблон использует «теневое поле» того же типа, что и обернутый объект внутри свойства. При использовании этого шаблона свойство будет создаваться только тогда, когда оно действительно необходимо («когда кто-то просит об этом»).

пример

В этом примере мы хотим управлять атрибутом с названием «title». Нам нужны сеттер, геттер и метод доступа к свойствам.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private String _title = "Untitled"; // shadow field
 
private StringProperty title;
 
public final String getTitle() {
    title == null ? return _title : title.get();
}
 
public final void setTitle(String newTitle) {
    if (title == null) {
        _title = newTitle;
    } else {
        title.set(newTitle);
    }
}
 
public final StringProperty titleProperty() {
    if (title == null) {
        /// !!!! pass shadow field to constructor
        title = new StringProperty(this, "title", _title);  
    }
 
    return title;
}

Используя этот шаблон, я смог уменьшить объем памяти с 310 МБ до 250 МБ для конкретного случая использования в моем проекте. Сохраненная память в десять раз превышает общую память моего компьютера, когда я был студентом. Просто подумай об этом!

Ссылка: JavaFX Совет 23: экономьте память! Теневые поля для свойств от нашего партнера JCG Дирка Леммермана в блоге Pixel Perfect .