Почему этот код работает медленнее и медленнее? - PullRequest
2 голосов
/ 20 апреля 2011

У меня есть класс сущности с именем SrcFile, и один из его столбцов:

@NotNull
@Lob
private Byte[] data;

Это SrcFile имеет отношение OneToOne с сущностью Report.

Из отчета.java:

@OneToOne
private SrcFile srcFile;

Сохранение сущности SrcFile прекрасно работает.

srcFileHomeFacade.clearInstance();
SrcFile srcFile = srcFileHomeFacade.getInstance();
byte[] bArray = resource.getBytesForSource();
srcFile.setData(ReportFileResource.toObject(bArray));
System.out.println("````````````````srcFile data length: "+bArray.length);
srcFileHomeFacade.persist();

Проблема возникает, когда я настаиваю Report.

Я делаю:

report.setSrcFile(srcFile);
reportHomeFacade.persist();

и работает хорошо, НО после многократного выполнения этого кода он становится все медленнее и медленнее (даже это вызывает ошибку служебной информации GC), и после нескольких часов исследования я обнаружил, что эта report.setSrcFile(srcFile) является проблемой.

Каким-то образом отчет не любит ссылаться на такую ​​сумму srcFile.data ...

Вы видите причину?

Если я прокомментирую report.setSrcFile, все отлично работает (за исключением того, что SRCFILE_ID в таблице отчетов будет нулевым, но это только для тестирования). Обратите внимание, что длина данных составляет около 100.000.

Примечание : Если я не сохраняю никаких report, а только srcFile сущностей, у меня нет проблем. UPDATE

«Работать медленнее и медленнее» объяснения: этот код вызывается для преобразования некоторых pcls в pdf, поэтому data содержит исходный код pcl и каждый раз отличается. После преобразования около 100 pcls процесс идет все медленнее и медленнее, и с помощью виртуальной машины я обнаружил этот массив byte [], который занимает много МБ памяти. Опять же, это определенно не проблема с IO, а с этим setSrcFile в объекте отчета, VisualVM также указывает на это.

Ответы [ 2 ]

2 голосов
/ 20 апреля 2011

Я все еще немного неуверен, но я подозреваю, что ваша проблема связана с тем, как вы сохраняете вещи и обрабатываете объекты сущностей: если вы правильно отбрасываете свои сущности после их сохранения, GC должен достаточно часто освобождать память, чтобы сохранить ваши Система работает без сбоев. Особенно если вы используете flush () или commit () после каждой транзакции, использование памяти вообще не должно увеличиваться. В вашем случае, однако, кажется, что все объекты хранятся в памяти даже после того, как они больше не нужны - поэтому должна быть какая-то причина, по которой ресурсы не освобождаются.

Вы случайно не используете один цикл for для итерации по набору srcFiles и имеете все вызовы persist () непосредственно внутри этого? Если это так, ваша проблема может быть связана с областью. Вы можете попытаться извлечь содержимое цикла в новый метод, чтобы все локальные переменные должным образом освобождались после каждой итерации.

Вы также можете улучшить ситуацию, установив CascadeType.PERSIST или CascadeType.ALL и используя одну операцию persist () для отчета, чтобы сохранить оба объекта. Также может помочь FetchType.LAZY.

В любом случае: поищите возможные причины, по которым ваша программа будет хранить все объекты, непосредственно доступные в памяти, вместо того, чтобы сохранять их в базе данных и впоследствии забывать о них.

0 голосов
/ 20 апреля 2011

Я помню, что нативный интерфейс JDBC с BLOB-объектами может быть сложным, и ручное закрытие () объектов вендора требовалось. Если этот шаг пропущен, большие двоичные объекты были накоплены в драйвере JDBC (то есть в памяти JVM), и в конечном итоге JVM вышла из строя.

Интересно, нужны ли вам какие-либо специфичные для поставщика свойства или действия для закрытия BLOB-объектов после сохранения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...