Я не уверен, как лучше всего структурировать мое веб-приложение Vaadin.Лучшая практика создания больших веб-приложений с несколькими видами, многими компонентами и проблемами с nemory
Предполагая, что в моем веб-приложении у нас есть много разных объектов View
с каждым количеством компонентов. Компоненты никогда не меняются, но данные в компонентах меняются при каждой странице.
Я вижу две возможности:
Создать и инициализировать все объекты сразу в конструкторе вида. Когда вызывается View's
enter(ViewChangeEvent event)
, привяжите данные к уже существующим объектам.Ничего не делать в конструкторе View. Создайте все компоненты в методе
enter(ViewChangeEvent event)
, привяжите данные к этим компонентам.
упрощенный пример двух различных подходов:
общественный класс ONEView расширяет VerticalLayout реализует View {
private TextField[] textfields = new TextField[VaadinprojectUI.TESTLIMIT];
public OneView() {
long startMs = Calendar.getInstance().getTimeInMillis();
for (int i=0;i<VaadinprojectUI.TESTLIMIT;i++){
TextField txtField = new TextField("Textfield #" + i);
textfields[i] = txtField;
addComponent(txtField);
}
long finishMs = Calendar.getInstance().getTimeInMillis();
System.out.println("OneView() - constructor" + (finishMs - startMs));
}
@Override
public void enter(ViewChangeEvent event) {
long startMs = Calendar.getInstance().getTimeInMillis();
for (int i=0;i<VaadinprojectUI.TESTLIMIT;i++){
textfields[i].setValue((String.valueOf(Math.random()*1000)));
}
long finishMs = Calendar.getInstance().getTimeInMillis();
System.out.println("OneView - enter()" + (finishMs - startMs));
}
ONEView будет сначала создать 1000 TextFields, добавить их к VerticalLayout, и хранить их в массиве для повторного использования. Когда OneView будет перемещен, он привяжет данные к текстовым полям.
public class TwoView extends VerticalLayout implements View{
public TwoView() {
//nothing in the constructor
}
@Override
public void enter(ViewChangeEvent event) {
long startMs = Calendar.getInstance().getTimeInMillis();
//entire load is in the "enter", only called upon navigation.
for (int i=0;i<VaadinprojectUI.TESTLIMIT;i++){
TextField txtField = new TextField("Textfield #" + i);
txtField.setValue((String.valueOf(Math.random()*1000)));
addComponent(txtField);
}
long finishMs = Calendar.getInstance().getTimeInMillis();
System.out.println("TwoView - enter()" + (finishMs - startMs));
}
TwoView ничего не будет делать в конструкторе, но всякий раз, когда он на навигацию, это создаст 1000 TextFields, и связать данные с ними. Текстовые поля не сохраняются и будут переделаны в другое время.
Некоторые испытания, навигации вперед и назад:
OneView() - constructor32
OneView - enter()14
TwoView - enter()28
OneView - enter()5
TwoView - enter()18
OneView - enter()3
TwoView - enter()12
При запуске приложения ONEView требуется некоторое время, чтобы создать его TextFields. Но после этого он всегда выполняет более быструю работу по привязке данных к своим текстовым полям (что ожидается).
Вопросы:
Какие компромиссы с использованием системы ONEView, когда дело доходит до управления памятью? Можем ли мы свободно создавать View after View в больших приложениях? У меня есть приложение Vaadin реального мира, в котором мы получаем OutOfMemoryErrors, и я чувствую, что это потому, что я оставляю столько места для многоразовых компонентов.
Что происходит, когда страница остается? В TwoView я предполагаю, что Garbage Collection уничтожает все и освобождает память. В OneView текстовые поля остаются в памяти с данными, назначенными им. Есть ли что-то как событие «exit()», когда пользователь оставляет представление, которое мы должны использовать для очистки данных в компонентах? Я думаю в случаях ComboBoxes или таблиц с большим количеством объектов в них, но они не очищаются после выхода страницы и забивают память, потому что они не получат GC'd?
Спасибо за любые советы
Вы сделали и проанализировали кучу кучи из своего приложения Vaadin реального мира, в котором есть проблемы с памятью? Вы должны уметь видеть, где используется большая часть памяти. Было бы интересно посмотреть, сколько памяти потребляет каждая пользовательская сессия. –