Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / ORM и переполнение памьяти / 20 сообщений из 20, страница 1 из 1
20.06.2012, 17:53:07
    #37847029
denis11111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ORM и переполнение памьяти
Для работы з БД использую 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
20.06.2012, 18:02:52
    #37847048
svenom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ORM и переполнение памьяти
denis11111 ,
Узнать, где они застревают и ликвидировать эту утечку. Где конкретно это происходит - ответ ищите в дампе JVM.
...
Рейтинг: 0 / 0
20.06.2012, 18:11:37
    #37847068
denis11111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ORM и переполнение памьяти
svenom denis11111 ,
Узнать, где они застревают и ликвидировать эту утечку. Где конкретно это происходит - ответ ищите в дампе JVM.
Меня интересует: это особенность EJB, или мой прокол.
...
Рейтинг: 0 / 0
20.06.2012, 18:25:22
    #37847100
svenom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ORM и переполнение памьяти
C вероятностью 99.9% это ваш косяк.
...
Рейтинг: 0 / 0
20.06.2012, 21:34:01
    #37847291
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ORM и переполнение памьяти
кеш первого уровня скорее всего. Чтобы не пересоздавать, используется один и тот же EntityManager. Так? Откуда берется таймер и откуда он берет EntityManager?
...
Рейтинг: 0 / 0
20.06.2012, 23:18:55
    #37847407
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ORM и переполнение памьяти
Blazkowiczкеш первого уровня скорее всего. Чтобы не пересоздавать, используется один и тот же EntityManager. Так? Откуда берется таймер и откуда он берет EntityManager?
+1 тоже хотел написать про кэш первого уровня
...
Рейтинг: 0 / 0
21.06.2012, 08:44:33
    #37847587
GKS_Samara
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ORM и переполнение памьяти
Добрый день, svenom!

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

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

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

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

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

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

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

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

код приведи.
Если ты добавил миллион объектов с разными ID то они все и будут в памяти.
...
Рейтинг: 0 / 0
22.06.2012, 11:13:11
    #37849867
denis11111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ORM и переполнение памьяти
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
22.06.2012, 11:22:07
    #37849883
svenom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ORM и переполнение памьяти
Судя по всему происходит следующее:
1) У вас есть EM, который инжектится в Stateless бин - пока что все ок
2) У вас есть Stateless Bean, который инжектится в ManagedBean - ну тоже вроде ок
3) НО! У вас ManagedBean является @ApplicationScoped, то есть один на все приложение. Вот тут у нас проблема.

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

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

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

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

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


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