powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / ORM и переполнение памьяти
20 сообщений из 20, страница 1 из 1
ORM и переполнение памьяти
    #37847029
denis11111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Для работы з БД использую EJB 3.0

Есть такой клас-сущность:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
@Entity
@Table(name = "bore_data")
public class BoreData implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;
    @JoinColumn(name = "bore_id", referencedColumnName = "id")
    @ManyToOne
    private Bores boreId;
    @Column(name = "log_time")
    @Temporal(TemporalType.TIMESTAMP)
    private Date logTime;

гет и сет
}



Ну вот добавляю я таблицу "bore_data" какие-то дание, скажем с помощью таймера на 1с. Где-то через сутку Джава машина зависает.
Проверил какие обьекты создаются в памяти и оказалось что всему виной клас сущности BoreData, их создается все больше и больше и все они висят в памяти, что и приводит к зависанию.
Как с этим бороться?
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37847048
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
denis11111 ,
Узнать, где они застревают и ликвидировать эту утечку. Где конкретно это происходит - ответ ищите в дампе JVM.
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37847068
denis11111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
svenom denis11111 ,
Узнать, где они застревают и ликвидировать эту утечку. Где конкретно это происходит - ответ ищите в дампе JVM.
Меня интересует: это особенность EJB, или мой прокол.
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37847100
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
C вероятностью 99.9% это ваш косяк.
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37847291
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кеш первого уровня скорее всего. Чтобы не пересоздавать, используется один и тот же EntityManager. Так? Откуда берется таймер и откуда он берет EntityManager?
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37847407
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Blazkowiczкеш первого уровня скорее всего. Чтобы не пересоздавать, используется один и тот же EntityManager. Так? Откуда берется таймер и откуда он берет EntityManager?
+1 тоже хотел написать про кэш первого уровня
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37847587
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, svenom!

> Узнать, где они застревают и ликвидировать эту утечку. Где конкретно это
> происходит - ответ ищите в дампе JVM.

Кстати, попробовал для этой цели использовать JProfiler.
Классная штука- берёшь любой объект (примерно как в JConsole) и говоришь
"а почему он живой"- и получаешь путь, из-за которого он ещё в памяти.
Утечки искать удобно.

Только он, зараза, платный.
Интересно- есть у бесплатных такой функционал?

--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37847702
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JDK/bin/jvisualvm.exe
Фича называется Find GC Roots по правому клику на объекте в дампе памяти.
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37847712
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eclipse TPTP тоже, говорят, умеет. Но я в него особо не вникал. VisualVM для текущих потребностей хватало с головой. С ним единственный геморрой это отладка Windows Service. Потому что он не видит просто так процессы работающие под другой учетной записью.
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37847813
GKS_Samara
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, Blazkowicz!

> JDK/bin/jvisualvm.exe
> Фича называется Find GC Roots по правому клику на объекте в дампе памяти.

Это дамп. А та по живому умеет. Но всё одно полезно, спасибо!

--
Алексей
JID: alxt@ya.ru
Posted
via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37847896
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GKS_SamaraЭто дамп. А та по живому умеет. Но всё одно полезно, спасибо!

Что значит "по живому" ? Состояние кучи постоянно меняется. Там нельзя "по живому". А jvisualvm точно так же по живому делает дамп (snapshot) и его можно анализировать.
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37848004
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
denis11111,

код приведи.
Если ты добавил миллион объектов с разными ID то они все и будут в памяти.
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37849867
denis11111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowiczкеш первого уровня скорее всего. Чтобы не пересоздавать, используется один и тот же EntityManager. Так? Откуда берется таймер и откуда он берет EntityManager?

В GlassFish есть такая настройка как : server-config->EJB Container->Cache Settings - вы про этот кеш?

EntityManager используется один, вот ДАО:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
@Stateless
public class BoreDataModel extends AbstractModel<BoreData> {
    
    @PersistenceContext(unitName = "VODOKANALPU1")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }
    
    public BoreDataModel(){
        super(BoreData.class);
    }
    
    public List<BoreData> findByBoreId(int boreId){
        String hql = "SELECT b FROM BoreData b WHERE b.boreId = :boreId";
        return getEntityManager().createQuery(hql).setParameter("boreId", boreId).getResultList();
    }
    
    public void removeAll(){
        String sql = "DELETE FROM bore_data";
        Query q = getEntityManager().createNativeQuery(sql);
        q.executeUpdate();
    }
    
}

//-----AbstractModel-----------------------------------------------------------

public abstract class AbstractModel<T> {

    private Class<T> entityClass;

    public AbstractModel(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        getEntityManager().persist(entity);
    }

    public void edit(T entity) {
        getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        return getEntityManager().createQuery(cq).getResultList();
    }

    public T find(Object id) {
        return getEntityManager().find(entityClass, id);
    }
}



А в бине все работает приблизительно так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
@ManagedBean(eager = true, name = "OPCForDB")
@ApplicationScoped
public class OPCForDB implements Serializable {
private BoreData current;
private Timer timer = null;

@EJB
 private BoreDataModel bdm;

@PostConstruct
private stF(){
current = new BoreData();

public void startTimer() {
       timer = new Timer(timeUpdate * 1000, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent ev) {
                getDataOPC();
            }
        });

} 

//---Этот метод и срабатывает в таймере и записывает дание в базу, через обьект bdm--------------------------------
private void getDataOPC() {
current..setLogTime(new Date()); 
bdm.create(current);
}

}
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37849883
svenom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Судя по всему происходит следующее:
1) У вас есть EM, который инжектится в Stateless бин - пока что все ок
2) У вас есть Stateless Bean, который инжектится в ManagedBean - ну тоже вроде ок
3) НО! У вас ManagedBean является @ApplicationScoped, то есть один на все приложение. Вот тут у нас проблема.

В итоге получается, что вы всегда работаете с одним и тем же ManagedBean, в который заинжктен один и тот же StatelessBean, в который заинжектен один и тот же инстанс EntityManager.
Это в корне неправильно, так как EntityManager по смыслу - легкий временный объект, он должен быть один на транзакцию, а у вас он один на приложение.

Варианты решения:
1) Инжектить не EntityManager, а EntityManagerFactory, из которой получать новый EM - тут я хз, не силен в JPA, может быть так нельзя делать.
2) В ManagedBean не инжектить StatelessBean, а вместо этого получать его через лукап
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37849929
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У Hibernate есть Stateless Session для подобных задач. Но не факт что оно доступно из JPA. Да и кто-то жаловался что оно не на столько Stateless, на сколько хотелось бы.
Использование Swing Timer в EJB приложении это не только странно, но ещё и то что спецификация настоятельно не рекомендует делать. Нужен или EJB таймер, или Quartz, хорошо интегрированый в контейнер.
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37849943
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
svenom1) Инжектить не EntityManager, а EntityManagerFactory, из которой получать новый EM - тут я хз, не силен в JPA, может быть так нельзя делать.

Должно быть можно. Как фикс на быструю руку, если поможет - самое то.
Но у меня есть серьезные подозрения что leak может остаться. Так как, у автора, JPA используется в (!sic) Event Dispatch Thread, то контейнер не сможет подчистить EntityManager в неуправляемом потоке. Его можно попробовать закрывать руками. Но сработает ли это, так сразу не скажешь.
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37850570
denis11111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczJDK/bin/jvisualvm.exe
Фича называется Find GC Roots по правому клику на объекте в дампе памяти.
Ну вот зашел я в нее, подключился к GlassFish, дальше выбрал Profiler, Memory, смотрю. на все обьекты, но там нет ничего про "Find GC Roots". В меня jdk1.7.0. Может я не правильно понял?

вменя в логе сервера мелькает такое:
"SEVERE: Exception in internal GC" - я так понял это не совсем хорошо... В гугле смотрел, вобще ни одного воспоминания про это.
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37850593
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
denis11111Ну вот зашел я в нее, подключился к GlassFish, дальше выбрал Profiler, Memory, смотрю. на все обьекты, но там нет ничего про "Find GC Roots". В меня jdk1.7.0. Может я не правильно понял?
Memory Profiler - показывает динамику изменений в памяти.
Для анализа связей нужно сделать дамп кучи и анализировать содержимое. Это не профилирование. Это анализ кучи. Разные вещи.
И зачем это вам? В чем проблема в вашем коде уже указали.
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37850604
denis11111
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczMemory Profiler - показывает динамику изменений в памяти.
Для анализа связей нужно сделать дамп кучи и анализировать содержимое. Это не профилирование. Это анализ кучи. Разные вещи.
И зачем это вам? В чем проблема в вашем коде уже указали.

Про проблему я понял, пока решаю. Хотел просто понять про что вы говорили.
До этого я и не знал что в Java\jdk1.7.0\bin есть какие-то вспомагательные програмки
...
Рейтинг: 0 / 0
ORM и переполнение памьяти
    #37850696
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
denis11111До этого я и не знал что в Java\jdk1.7.0\bin есть какие-то вспомагательные програмкиОни и в 1.6 есть. И в 1.4.2 :)
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / ORM и переполнение памьяти
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]