Interesting detective work, Kurt. Thanks. Why the WebService version of the app would behave differently as far as GC is concerned is a mystery. And, you said that plugging in Hibernate into this scenario, everything works okay? Very confusing.
How are you performing the Entity enhancement processing? Are you pre-enhancing via your build process? Or, are you using the -javaagent mechanism? Or, are you falling back to the subclassing support within OpenJPA? (See [1] for more information on these questions in case they don't make sense.) This would be one area that is different between Hibernate and OpenJPA -- enhancement processing. In the Tomcat environment, you may be falling back to the subclassing support (which we do not recommend) and hitting a memory leak with that. You said OpenJPA 1.2.x, right? Just a couple of thoughts on the subject... Kevin [1] http://webspherepersistence.blogspot.com/2009/02/openjpa-enhancement.html On Wed, Jan 13, 2010 at 4:25 PM, Kurt T Stam <[email protected]> wrote: > The same code executed straight from a java client (inVM) shows no memory > leak. > > So is the fact that it is WebService significant then? What else can be > different? I think one thread remains up, and somehow this causes openjpa > not being able to clean up after itself. What can I do to debug this more? I > can actually see in the profiler that the objects are allocated by the > WebService, but why aren't they cleaned up? > > Thx, > > > --Kurt > > > Kurt T Stam wrote: > >> Thanks Kevin, thanks for your response. >> >> I just replaced the static call by: >> >> apiAuthToken = new org.uddi.api_v3.AuthToken(); >> apiAuthToken.setAuthInfo(modelAuthToken.getAuthToken()); >> //MappingModelToApi.mapAuthToken(modelAuthToken, >> apiAuthToken); >> >> which did not make a difference. >> >> I'm wondering if the fact that my class is a webservice makes a >> difference. I'll try extracting it into >> a regular class with a main method and profile that. At least I know that >> I didn't forget something >> completely obvious.. >> >> --Kurt >> >> Kevin Sutter wrote: >> >>> Kurt, >>> I agree that this is very common usage of the JPA programming model. >>> And, >>> we are not aware of any memory leaks. About the only thing that jumps >>> out >>> at me is the following two lines: >>> >>> apiAuthToken = new org.uddi.api_v3.AuthToken(); >>> MappingModelToApi.mapAuthToken(modelAuthToken, >>> apiAuthToken); >>> >>> What do these do? Can you comment these out and see if the memory leak >>> still exists? Since you are passing the modelAuthToken into this method, >>> I >>> don't know what it's doing with the reference and could it be holding >>> onto >>> something to prevent the GC from cleaning up? >>> >>> The rest of your example seems very straight forward with creating and >>> persisting objects. >>> >>> Kevin >>> >>> On Wed, Jan 13, 2010 at 2:09 PM, Rick Curtis <[email protected]> wrote: >>> >>> >>> >>>> If you change the 1000 to something like 1000000... does your >>>> application >>>> go >>>> OOM? Are you running in a JSE environment? What is PersistenceManager? >>>> >>>> On Wed, Jan 13, 2010 at 2:05 PM, Kurt T Stam <[email protected]> >>>> wrote: >>>> >>>> >>>> >>>>> BTW I'm running with the cache off >>>>> >>>>> <property name="openjpa.DataCache" value="false"/> >>>>> >>>>> (that turns it off right?) >>>>> >>>>> --Kurt >>>>> >>>>> >>>>> >>>>> Kurt T Stam wrote: >>>>> >>>>> >>>>> >>>>>> Hi guys, >>>>>> >>>>>> [DESCRIPTION] The code below inserts a 1000 records in the database. >>>>>> >>>>>> for (int i=1; i<1000; i++) { >>>>>> EntityManager em = PersistenceManager.getEntityManager(); >>>>>> EntityTransaction tx = em.getTransaction(); >>>>>> try { >>>>>> tx.begin(); >>>>>> // Generate auth token and store it! >>>>>> String authInfo = AUTH_TOKEN_PREFIX + UUID.randomUUID(); >>>>>> org.apache.juddi.model.AuthToken modelAuthToken = new >>>>>> org.apache.juddi.model.AuthToken(); >>>>>> if (authInfo != null) { >>>>>> modelAuthToken.setAuthToken(authInfo); >>>>>> modelAuthToken.setCreated(new Date()); >>>>>> modelAuthToken.setLastUsed(new Date()); >>>>>> modelAuthToken.setAuthorizedName(publisherId); >>>>>> modelAuthToken.setNumberOfUses(0); >>>>>> modelAuthToken.setTokenState(AUTHTOKEN_ACTIVE); >>>>>> em.persist(modelAuthToken); >>>>>> } >>>>>> apiAuthToken = new org.uddi.api_v3.AuthToken(); >>>>>> MappingModelToApi.mapAuthToken(modelAuthToken, >>>>>> apiAuthToken); >>>>>> tx.commit(); >>>>>> } finally { >>>>>> if (tx.isActive()) { >>>>>> tx.rollback(); >>>>>> } >>>>>> em.clear(); >>>>>> em.close(); >>>>>> } >>>>>> } >>>>>> >>>>>> >>>>>> [ISSUE] >>>>>> After it leaving this code I end up with a 1000 >>>>>> org.apache.juddi.model.AuthToken objects in memory. I've been using >>>>>> the >>>>>> profiler, and these objects cannot be garbage collected. >>>>>> >>>>>> This seems to be pretty the most common use case of using an >>>>>> OR-mapping >>>>>> tool, so I find it hard to believe openjpa has a memory leak here. >>>>>> Does >>>>>> anyone see what I'm doing wrong? Or can someone point me to an example >>>>>> >>>>>> >>>>> that >>>> >>>> >>>>> does not exhibit this behavior? BTW same code using hibernate does not >>>>>> accumulate these objects. >>>>>> >>>>>> We're using openjpa 1.2.1. >>>>>> >>>>>> >>>>>> Thx, >>>>>> >>>>>> >>>>>> Kurt >>>>>> >>>>>> Apache jUDDI. >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>> -- >>>> Thanks, >>>> Rick >>>> >>>> >>>> >>> >>> >>> >> >> >
