[hibernate-issues] [Hibernate-JIRA] Updated: (HHH-2631) Leaking PreparedStatement and ResultSet via CollectionLoadContext instances maintained in Map collectionLoadContexts in LoadContexts

Gail Badner (JIRA) noreply at atlassian.com
Fri Jun 1 01:50:04 EDT 2007


     [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-2631?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Gail Badner updated HHH-2631:
-----------------------------

    Attachment: HHH-2631.patch

I am attaching a patch that removes references to ResultSet objects from CollectionLoadContext and LoadContexts when they are no longer needed, and removes CollectionKey objects from CollectionLoadContext.localLoadingCollectionKeys as they are processed by CollectionLoadContext.endLoadingCollections(CollectionPersister persister).

In CollectionLoadContext.endLoadingCollections(CollectionPersister persister), I noticed that it would be more efficient to iterate over localLoadingCollectionKeys rather than loadContexts.getLoadingCollectionEntryMap().entrySet(), since it can be a much smaller set and each element will refer to a collection being loaded from the relevant ResultSet. This patch makes this change in iterator.

I used loadContexts.locateLoadingCollectionEntry( collectionKey ) to get the LoadingCollectionEntry. When a match in Persister and ResultSet is found, iter.remove() removes the CollectionKey from localLoadingCollectionKeys and a new method, loadContexts.unregisterLoadingCollectionEntry( collectionKey ), is called to remove the entry from the cross-reference map in loadContexts. 

When all elements of localLoadingCollectionKeys have been removed, then all collections that are loaded from the ResultSet have been processed and the CollectionLoadContext object (and its ResultSet reference) is no longer needed. A new method, loadContexts.removeCollectionLoadContext(this), is called to  remove the two references to the ResultSet object in loadContexts.collectionLoadContexts (the key and in the CollectionLoadContext value). 

I'm not completely sure that it is appropriate to remove the CollectionLoadContext from loadContexs.collectionLoadContexts after the last CollectionKey in  localLoadingCollectionKeys is processed. Would it be better to call LoadContexts.cleanup() when the session is being closed?

I've verified that no unit tests are broken by this patch.

> Leaking PreparedStatement and ResultSet via CollectionLoadContext instances maintained in Map collectionLoadContexts in LoadContexts
> ------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: HHH-2631
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2631
>             Project: Hibernate3
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 3.2.4
>         Environment: hibernate 3.2.3 with patch from HHH-2553
>            Reporter: Douglas A. Herrick
>            Assignee: Steve Ebersole
>             Fix For: 3.2.5, 3.3
>
>         Attachments: HHH-2631.patch
>
>
> While diagnosing an apparent resource issue, while running our application for a couple of hours I noticed over time that the number of PreparedStatement and ResultSet instances continued to grow, eventually consuming a fair amount of memory.  After digging around a bit, I saw that the entries LoadContext.java inserts into the map named collectionLoadContexts are not removed from the map [method cleanup(ResultSet resultSet)  might have removed them, but I never witnessed its invocation, nor did I find any references to it).
> I pasted below a stack trace that shows the insertion of elements into collectionLoadContexts:
> Thread [http-9943-Processor2] (Suspended (breakpoint at line 53 in CollectionLoadContext))	
> 	CollectionLoadContext.<init>(LoadContexts, ResultSet) line: 53	
> 	LoadContexts.getCollectionLoadContext(ResultSet) line: 85	
> 	BasicCollectionLoader(Loader).handleEmptyCollections(Serializable[], Object, SessionImplementor) line: 1060	
> 	BasicCollectionLoader(Loader).doQuery(SessionImplementor, QueryParameters, boolean) line: 690	
> 	BasicCollectionLoader(Loader).doQueryAndInitializeNonLazyCollections(SessionImplementor, QueryParameters, boolean) line: 236	
> 	BasicCollectionLoader(Loader).loadCollection(SessionImplementor, Serializable, Type) line: 1994	
> 	BasicCollectionLoader(CollectionLoader).initialize(Serializable, SessionImplementor) line: 36	
> 	BasicCollectionPersister(AbstractCollectionPersister).initialize(Serializable, SessionImplementor) line: 565	
> 	DefaultInitializeCollectionEventListener.onInitializeCollection(InitializeCollectionEvent) line: 60	
> 	SessionImpl.initializeCollection(PersistentCollection, boolean) line: 1716	
> 	PersistentSet(AbstractPersistentCollection).forceInitialization() line: 454	
> 	StatefulPersistenceContext.initializeNonLazyCollections() line: 785	
> 	QueryLoader(Loader).doQueryAndInitializeNonLazyCollections(SessionImplementor, QueryParameters, boolean) line: 241	
> 	QueryLoader(Loader).doList(SessionImplementor, QueryParameters) line: 2220	
> 	QueryLoader(Loader).listIgnoreQueryCache(SessionImplementor, QueryParameters) line: 2104	
> 	QueryLoader(Loader).list(SessionImplementor, QueryParameters, Set, Type[]) line: 2099	
> 	QueryLoader.list(SessionImplementor, QueryParameters) line: 378	
> 	QueryTranslatorImpl.list(SessionImplementor, QueryParameters) line: 338	
> 	HQLQueryPlan.performList(QueryParameters, SessionImplementor) line: 172	
> 	SessionImpl.list(String, QueryParameters) line: 1121	
> 	QueryImpl.list() line: 79	
> 	HibQuery.list() line: 60	
> 	HibRepository(AbstractRepository).query(IQuery, Class) line: 300	
>    ...
> While subsequent to this logic, hibernate does close the PreparedStatement and ResultSet instances, since it never removes them from collectionLoadContexts map, those instances are never GCed.  After running our application for a couple of days the amount of storage attributed to this potential leak is significant.

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list