Я борюсь с проблемой, которую я использую в EOF-структуре Apple довольно долгое время. Похоже, что иногда, когда создается EOEnterpriseObject или втягивается в контекст редактирования из БД, EOF не отпускает память, которую объект потребляет, даже после того, как соответствующий объект предприятия, контекст редактирования и хранилище объектов расположены и удалены. Похоже, что большинство объектов обрабатываются EOF очень просто, но у меня есть 2 объекта, где EOF последовательно удерживает память, используемую объектами, до тех пор, пока приложение не будет перезапущено. Оба эти ОР потенциально очень большие (они содержат объект NSData, который используется для хранения вложения файла).Утечка памяти в WebObjects
Используя JProfiler, я обнаружил, что ссылка на проблему EOS хранится в массиве EODatabase._snapshots.
Мне было интересно, если бы у кого-то еще была аналогичная проблема с EOF и/или проектом Wonder. Поскольку я постоянно вижу проблему в двух разных сценариях, я надеюсь, что это будет довольно распространенным явлением, и поэтому имеет разрешение ...
Я использую последнюю библиотеку WebObjects (5.4.3) и последнюю версию Wonder библиотеки.
Ниже не мой точный код, но это самый маленький, можно пример, который до сих пор имеет место утечка памяти:
`
public WOActionResults createEmailHistoryEntry() throws MessagingException, IOException {
File emailFile = new File("Email_with_large_attachment.eml");
javax.mail.Message message = EmailUtils.convertEmlToMessage(emailFile);
EOObjectStore osc = new ERXObjectStoreCoordinator(true);
EOEditingContext ec = ERXEC.newEditingContext(osc);
ec.lock();
try {
EmailHistoryEntry historyEntry = (EmailHistoryEntry) EOUtilities.createAndInsertInstance(ec, EmailHistoryEntry.class.getSimpleName());
EmailDataObject emailData = (EmailDataObject) EOUtilities.createAndInsertInstance(ec, EmailDataObject.class.getSimpleName());
emailData.setEmailHistoryEntry(historyEntry);
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
message.writeTo(byteStream);
NSData rawEmail = new NSData(byteStream.toByteArray());
emailData.setRawEmail(rawEmail);
ec.saveChanges();
}
finally {
ec.unlock();
ec.dispose();
osc.dispose();
}
return null;
}
`
Я не знаю, что Я делаю там что-то необычное ... Если я запустил его несколько раз, потребление памяти будет расти примерно на 140 МБ каждый раз и в конечном итоге ударит ошибку из-за памяти.
2012-12-26 -`
Я сделал еще некоторые исследования по этому вопросу. Похоже, что проблема заключается в библиотеке Project Wonder, а не в библиотеке EOF. Я понимаю, что «проблема» может быть мной и/или моим пониманием, а не Wonder lib ... :)
Я создал тестовое приложение, которое дублирует проблему, которую я видел, и разместил ее на github: https://github.com/t-evans/memory-leak-test.git.
Приложение для тестирования в основном просто приложение по умолчанию, которое создает Eclipse при добавлении нового приложения Wonder. Изменения включают добавление одной строки в Application.java, большую часть кода в Main.java и, конечно же, файл модели. В настоящее время он настроен на подключение к базе данных postgres с именем «memleaktest».
Конфигурация запуска приложения имеет только два аргумента VM: «-Xmx5m -Xmx50m». Если я запустил приложение и нажимаю ссылку «Создать объект» примерно 5 раз, он попадет в ошибку OutOfMemory. Мониторинг памяти с помощью jConsole показывает, что потребление памяти растет примерно на 5 МБ каждый раз, и приложение никогда не отпускает эти 5 МБ.
Мои выводы до сих пор указывают на ERXObjectStoreCoordinatorSynchronizer в качестве виновника. В тестовом приложении Application.java включает синхронизацию. Конструктор Main.java просто выполняет фиктивный запрос, что в конечном итоге приводит к передаче Main._osc в ERXObjectStoreCoordinatorSynchronizer.addObjectStore() (синхронизатору требуется более 1 OSC для синхронизации чего-либо). Main.createDataStore() создает OSC и EC, добавляет объект DataStore в БД, затем уничтожает OSC и EC.
ПОСЛЕ того, как новый объект, OSC и EC сбрасываются, удаляются и выходят из сферы действия, синхронизатор запускается и добавляет этот вновь созданный (но теперь устаревший) объект к этому другому OSC, добавляет новый объект в базу данных EOD._snapshots array, где он остается до тех пор, пока не останется другой OSC.
Это кажется странным, что новый EO синхронизируется с другим OSC после его, и это ЕС и OSC, мертв, и пропал, и из области видимости. Не следует ли синхронизировать синхронизацию того факта, что EO выходит за пределы области действия и удаляет ее из всех остальных OSC (или не добавляет ли она других OSCs в первую очередь)?
Я знаю, что синхронизация может быть отключена путем вызова
ERXObjectStoreCoordinatorSynchronizer.synchronizer() setDefaultSettings (новые SynchronizerSettings (ложь, ложь, ложь, ложь)).
, который позволит избежать проблем, но настройки по умолчанию для синхронизатора есть все включается, что вызывает довольно большую утечку ...
Является ли это ошибка, или я делаю что-то неправильно? Я смущен, почему другие люди, похоже, не сталкиваются с этим ... или, может быть, они сталкиваются с этим, но не заметили утечку памяти, потому что они не используют большие ОР (?)
Спасибо за ответ! Я был немного удивлен, чтобы получить ответ на вопрос в WebObject связанного здесь. – Troy
Я отредактировал мое сообщение выше с некоторыми подробностями моего теста. Проблема может быть в моем коде, но я не вижу, где это может быть ... – Troy
Я пересмотрел свой первоначальный вопрос, чтобы добавить немного больше объяснений и ссылку в тестовое приложение, которое дублирует проблему, которую я видел. Надеюсь, это поможет указать мою ошибку (или ошибку проекта Wonder). – Troy