Добавление нескольких тысяч элементов в ComboBox
НЕ является эффективным, когда вы начинаете масштабирование пользователей. Помните, что все это спрятано в HttpSession
. Если вы не очень осторожны, ваше потребление памяти будет расти.
Недавно я провел простой тест для профилирования приложения, которое использовало IndexedContainer
против BeanItemContainer
, и объем используемой памяти ОЧЕНЬ отличался. Тестируемый BeanItem
был постоянным объектом JPA со многими взаимосвязями и свойствами. Для выпадающего списка нам действительно нужны только два свойства: id и name.
BeanItemContainer
потребляет 50 МБ на пользователя против 2 МБ на пользователя для IndexedContainer
. Таким образом, как вы можете видеть, он не будет хорошо масштабироваться, если вы не будете осторожны с тем, какой тип информации хранится в сеансе. ИМХО даже 2 МБ не является удовлетворительным, и лучший дизайн вместо этого будет использовать ленивый контейнер запросов.
BeanItemContainer
существенно создаст копию каждого поля / ассоциации, независимо от того, содержит ли оно данные или нет, на которые приходится большая часть различий в памяти. Плагин Eclipse Memory Analyzer очень удобен для анализа дампов кучи:)
class EditViewTest {
private ComboBox comboBox
@Test
void serialize() {
BeanItemContainer<Organization> container = new BeanItemContainer<Organization>(Organization)
container.addAll(getAllOrgs().sort({ a, b -> a.name <=> b.name }))
comboBox = new ComboBox('Organization', container)
comboBox.setItemCaptionMode(Select.ITEM_CAPTION_MODE_PROPERTY)
comboBox.setItemCaptionPropertyId("name")
long fileLength
def temp = File.createTempFile('orgs','.ser')
try {
temp.withObjectOutputStream { out ->
out << comboBox
}
fileLength = temp.length()
}
finally {
temp.delete()
}
println fileLength / 1024 / 1024
HeapDumper.dumpHeap('serialize.bin', true)
Thread.sleep(10000L)
}
@Test
void serialize2() {
comboBox = new ComboBox()
getAllOrgs().each { Organization org ->
comboBox.addItem(org.id)
comboBox.setItemCaption(org.id, org.name)
}
long fileLength
def temp = File.createTempFile('orgs','.ser')
try {
temp.withObjectOutputStream { out ->
out << comboBox
}
fileLength = temp.length()
}
finally {
temp.delete()
}
println fileLength / 1024 / 1024
HeapDumper.dumpHeap('serialize2.bin', true)
Thread.sleep(10000L)
}
private List getAllOrgs() {
def orgs = []
3197.times {
orgs << new Organization(id: UUID.randomUUID().toString(),
company: new Company(name: RandomStringUtils.randomAscii(24)))
}
return orgs
}
}
Вы можете использовать HotSpotDiagnosticMXBean
для программного дампа кучи с Oracle JVM или 'com.ibm.jvm.Dump.HeapDump ()' для IBM JDK.
2 МБ кучи потреблено (сериализовано: 0,33 МБ) против 50 МБ (сериализовано: 13,12 МБ)
YMMV в зависимости от используемой платформы / JDK.