You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomee.apache.org by cocorossello <co...@gmail.com> on 2018/02/07 15:44:25 UTC

JtaEntityManager GC

Hi,

We are having some memory problems in our applications. We are using tomee
7.0.4 with eclipselink, no second cache level. Most of the application are
@ApplicationScoped. 

Transaction is managed by container (JTA), no extended transactions at all,
everything we do with persistence is through the entity manager, which is
always injected with:
    @PersistenceContext(unitName = "travelcPU")
    private EntityManager entityManager;


I have isolated one production server, and waited until all sessions are
dead and then flushed all caches and then I took a heapdump. It's still
1.6Gb, even with no information, I think it's quite big.

I can see in the heapdump some 22K
org.apache.openejb.persistence.JtaEntityManager . And then (And I'm not sure
if it's related to JtaEntityManager)  a lot of QueryBasedValueHolder which
are in fact holding references to a lot of our domain objects.

So, my question is, shouldn't those JtaEntityManager be cleared on GC? I
think that they don't hold references to the eclipselink EnityManager, so
the problem probably comes from another part, but can you confirm?

Thanks in advance.



--
Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-f979441.html

Re: JtaEntityManager GC

Posted by Matthew Broadhead <ma...@nbmlaw.co.uk>.
you might be able to use a @Qualifier to have 2 different producers

On 19/02/2018 21:43, cocorossello wrote:
> Thx Chongma, but one question.
>
> Let's say I also want to use that MyRepo1 from a @Stateless @Scheduled (so
> no request context). How can I produce that same entityManager?
>
>
>
> --
> Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-f979441.html


Re: JtaEntityManager GC

Posted by Matthew Broadhead <ma...@nbmlaw.co.uk>.
sorry i misread the question.  you should still be able to @Inject into 
a @Stateless without a @RequestContext?
for my timer classes i used this example
http://tomee.apache.org/examples-trunk/schedule-expression/README.html
an @EJB @Singleton initialised with TimerConfig

On 19/02/2018 21:43, cocorossello wrote:
> Thx Chongma, but one question.
>
> Let's say I also want to use that MyRepo1 from a @Stateless @Scheduled (so
> no request context). How can I produce that same entityManager?
>
>
>
> --
> Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-f979441.html


Re: JtaEntityManager GC

Posted by Romain Manni-Bucau <rm...@gmail.com>.
it was supposed to be done on leaf call on the dsl


Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>

2018-02-19 23:33 GMT+01:00 cocorossello <co...@gmail.com>:

> Romain, one question. You said that if I was using it outside a
> transaction I
> should clear myself the entityManager.
>
> But looking at the JtaEntityManager it does nothing in that case:
>
>     public void clear() {
>         if (!extended && !isTransactionActive()) {
>             return;
>         }
>         ....
>     }
>
> How can I clear the entityManager?
>
>
>
> --
> Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-
> f979441.html
>

Re: JtaEntityManager GC

Posted by cocorossello <co...@gmail.com>.
Romain, one question. You said that if I was using it outside a transaction I
should clear myself the entityManager.

But looking at the JtaEntityManager it does nothing in that case:

    public void clear() {
        if (!extended && !isTransactionActive()) {
            return;
        }
        ....
    }

How can I clear the entityManager?



--
Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-f979441.html

Re: JtaEntityManager GC

Posted by cocorossello <co...@gmail.com>.
Thx Chongma, but one question.

Let's say I also want to use that MyRepo1 from a @Stateless @Scheduled (so
no request context). How can I produce that same entityManager?



--
Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-f979441.html

Re: JtaEntityManager GC

Posted by Matthew Broadhead <ma...@nbmlaw.co.uk>.
i was told to inject the entitymanager like this
@ApplicationScoped
public class EntityManagerProducer {
     @PersistenceUnit(unitName = "myDb")
     private EntityManagerFactory entityManagerFactory;

     @Produces
     @Default
     @RequestScoped
     public EntityManager create() {
         return this.entityManagerFactory.createEntityManager();
     }

     public void dispose(@Disposes @Default EntityManager entityManager) {
         if (entityManager.isOpen()) {
             entityManager.close();
         }
     }
}
injecting into your example like:
@ApplicationScoped
public class MyRepo1{
     @Inject
     private EntityManager em;

     public List<Something> loadSomeStuff(){  //Non transactional
         em.createQuery(....).getResultList();
     }
}
also with JSF i alway found @PostConstruct a bit dodgy.  way better to add
<f:metadata>
      <f:viewAction action="#{myViewBean.onload}" />
</f:metadata>
then in your bean you have an onload function (no annotation necessary)
public String onload() {
     someVar1= myRepo1.loadSomeStuff();
     someVar2 = myRepo2.loadSomeStuff();
     return null;  //you can call action here if necessary
}

On 13/02/2018 09:42, cocorossello wrote:
> Hi,
>
> Calling entityManager.clear() seems the best approach since most of the
> queries are not executed inside a transaction. But I have no idea on where I
> should use it or what would be a good implementation pattern.
>
> I mean, let's say I have a @ViewScoped with a couple of injected
> @ApplicationScoped.
>
> @ViewScoped
> public class MyViewBean{
>
> @Inject
> private MyRepo1 myRepo1;
>
> @Inject
> private MyRepo2 myRepo2;
>
> @PostConstruct
> void init(){
>     someVar1= myRepo1.loadSomeStuff();
>     someVar2 = myRepo2.loadSomeStuff();
> }
> ..
> }
>
> @ApplicationScoped
> public class MyRepo1{
>      @PersistenceContext(unitName = "myUnit")
>      private EntityManager entityManager;
>
>      public List<Something> loadSomeStuff(){  //Non transactional
>          entityManager.createQuery(....).getResultList();
>      }
> }
>
> }
>
> So, should I call entityManager.clear() after all non transactional queries
> (or at least some of them)? Can I do it in some web filter?
>
> This seems pretty basic stuff but I can't get it right...
>
>
>
> --
> Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-f979441.html


Re: JtaEntityManager GC

Posted by Romain Manni-Bucau <rm...@gmail.com>.
tomee closes the EM after the transaction, if you need to call clear() it
means the close doesnt release the data in your provider - can be a bug.

In terms of pattern you need to clear it when you don't need it anymore. A
way to do it is a Synchronization and register it in the transaction
synchronization registry - what we do by default. Now if you don't have any
transaction it is after your last usage. The repo being not transactional
and application scoped can justify a leak, if you put it request scoped
(view scoped if you can) or @Transactional it should get fixed.


Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>

2018-02-13 9:42 GMT+01:00 cocorossello <co...@gmail.com>:

> Hi,
>
> Calling entityManager.clear() seems the best approach since most of the
> queries are not executed inside a transaction. But I have no idea on where
> I
> should use it or what would be a good implementation pattern.
>
> I mean, let's say I have a @ViewScoped with a couple of injected
> @ApplicationScoped.
>
> @ViewScoped
> public class MyViewBean{
>
> @Inject
> private MyRepo1 myRepo1;
>
> @Inject
> private MyRepo2 myRepo2;
>
> @PostConstruct
> void init(){
>    someVar1= myRepo1.loadSomeStuff();
>    someVar2 = myRepo2.loadSomeStuff();
> }
> ..
> }
>
> @ApplicationScoped
> public class MyRepo1{
>     @PersistenceContext(unitName = "myUnit")
>     private EntityManager entityManager;
>
>     public List<Something> loadSomeStuff(){  //Non transactional
>         entityManager.createQuery(....).getResultList();
>     }
> }
>
> }
>
> So, should I call entityManager.clear() after all non transactional queries
> (or at least some of them)? Can I do it in some web filter?
>
> This seems pretty basic stuff but I can't get it right...
>
>
>
> --
> Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-
> f979441.html
>

Re: JtaEntityManager GC

Posted by cocorossello <co...@gmail.com>.
Hi,

Calling entityManager.clear() seems the best approach since most of the
queries are not executed inside a transaction. But I have no idea on where I
should use it or what would be a good implementation pattern.

I mean, let's say I have a @ViewScoped with a couple of injected
@ApplicationScoped. 

@ViewScoped
public class MyViewBean{

@Inject
private MyRepo1 myRepo1;

@Inject
private MyRepo2 myRepo2;

@PostConstruct
void init(){
   someVar1= myRepo1.loadSomeStuff();
   someVar2 = myRepo2.loadSomeStuff();
}
..
}

@ApplicationScoped
public class MyRepo1{
    @PersistenceContext(unitName = "myUnit")
    private EntityManager entityManager;

    public List<Something> loadSomeStuff(){  //Non transactional
        entityManager.createQuery(....).getResultList();
    }
}

}

So, should I call entityManager.clear() after all non transactional queries
(or at least some of them)? Can I do it in some web filter? 

This seems pretty basic stuff but I can't get it right...



--
Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-f979441.html

Re: JtaEntityManager GC

Posted by Romain Manni-Bucau <rm...@gmail.com>.
With Eclipselink take care it can trigger some unexpected connection if you
use without willing it lazy fetching (in a view for instance). This is an
easy way to leak :(.


Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>

2018-02-08 11:41 GMT+01:00 cocorossello <co...@gmail.com>:

> My xmx is 11g right now, I need it this way or production environment will
> end up doing full gc. The heapdump is taken after a GC.
>
> I think the problem comes from eclipselink. We have some caches. Those
> caches are storing some entities which are in fact storing lazy relations.
>
> In case of a batchfetch (or joinfetch), eclipselink needs to store the
> original query that was performed to get the result. I guess that the
> problem comes from this, as I can see a lot of QueryBasedValueHolder
> objects....
>
>
>
>
>
>
> --
> Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-
> f979441.html
>

Re: JtaEntityManager GC

Posted by cocorossello <co...@gmail.com>.
My xmx is 11g right now, I need it this way or production environment will
end up doing full gc. The heapdump is taken after a GC.

I think the problem comes from eclipselink. We have some caches. Those
caches are storing some entities which are in fact storing lazy relations. 

In case of a batchfetch (or joinfetch), eclipselink needs to store the
original query that was performed to get the result. I guess that the
problem comes from this, as I can see a lot of QueryBasedValueHolder
objects.... 






--
Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-f979441.html

Re: JtaEntityManager GC

Posted by Paul Carter-Brown <pa...@opposablethumbs.io>.
What is your xmx setting and did you force a gc prior to taking the heap
dump?

On your db have you checked if there are any long running transactions

On 7 Feb 2018 5:44 pm, "cocorossello" <co...@gmail.com> wrote:

> Hi,
>
> We are having some memory problems in our applications. We are using tomee
> 7.0.4 with eclipselink, no second cache level. Most of the application are
> @ApplicationScoped.
>
> Transaction is managed by container (JTA), no extended transactions at all,
> everything we do with persistence is through the entity manager, which is
> always injected with:
>     @PersistenceContext(unitName = "travelcPU")
>     private EntityManager entityManager;
>
>
> I have isolated one production server, and waited until all sessions are
> dead and then flushed all caches and then I took a heapdump. It's still
> 1.6Gb, even with no information, I think it's quite big.
>
> I can see in the heapdump some 22K
> org.apache.openejb.persistence.JtaEntityManager . And then (And I'm not
> sure
> if it's related to JtaEntityManager)  a lot of QueryBasedValueHolder which
> are in fact holding references to a lot of our domain objects.
>
> So, my question is, shouldn't those JtaEntityManager be cleared on GC? I
> think that they don't hold references to the eclipselink EnityManager, so
> the problem probably comes from another part, but can you confirm?
>
> Thanks in advance.
>
>
>
> --
> Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-
> f979441.html
>

Re: JtaEntityManager GC

Posted by sgjava <sg...@gmail.com>.
Have you tried MAT https://www.eclipse.org/mat to analyze the heap?



--
Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-f979441.html

Re: JtaEntityManager GC

Posted by Romain Manni-Bucau <rm...@gmail.com>.
Hi,

normally they are garbaged collected once the transaction ends. If you use
it without transaction you can need to call clear() once you are done.


Romain Manni-Bucau
@rmannibucau <https://twitter.com/rmannibucau> |  Blog
<https://rmannibucau.metawerx.net/> | Old Blog
<http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book
<https://www.packtpub.com/application-development/java-ee-8-high-performance>

2018-02-07 16:44 GMT+01:00 cocorossello <co...@gmail.com>:

> Hi,
>
> We are having some memory problems in our applications. We are using tomee
> 7.0.4 with eclipselink, no second cache level. Most of the application are
> @ApplicationScoped.
>
> Transaction is managed by container (JTA), no extended transactions at all,
> everything we do with persistence is through the entity manager, which is
> always injected with:
>     @PersistenceContext(unitName = "travelcPU")
>     private EntityManager entityManager;
>
>
> I have isolated one production server, and waited until all sessions are
> dead and then flushed all caches and then I took a heapdump. It's still
> 1.6Gb, even with no information, I think it's quite big.
>
> I can see in the heapdump some 22K
> org.apache.openejb.persistence.JtaEntityManager . And then (And I'm not
> sure
> if it's related to JtaEntityManager)  a lot of QueryBasedValueHolder which
> are in fact holding references to a lot of our domain objects.
>
> So, my question is, shouldn't those JtaEntityManager be cleared on GC? I
> think that they don't hold references to the eclipselink EnityManager, so
> the problem probably comes from another part, but can you confirm?
>
> Thanks in advance.
>
>
>
> --
> Sent from: http://tomee-openejb.979440.n4.nabble.com/TomEE-Users-
> f979441.html
>