Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 420502 - Window cache leaks file handles
Summary: Window cache leaks file handles
Status: RESOLVED FIXED
Alias: None
Product: JGit
Classification: Technology
Component: JGit (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows 7
: P3 normal with 1 vote (vote)
Target Milestone: 3.2   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-10-28 09:23 EDT by Kristian Rosenvold CLA
Modified: 2013-11-26 03:31 EST (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kristian Rosenvold CLA 2013-10-28 09:23:43 EDT
The window cache leaks file handles which leaves locked files on windows.

This bug is discussed at http://mail-archives.apache.org/mod_mbox/maven-dev/201310.mbox/%3CCAJZRQKzQUt-usHvpf6-icbvhM5wMUecnwEvh0rMdbAhG1NDYCQ%40mail.gmail.com%3E

It would appear the file descriptor that is being created at pack.beginWindowCache in WindowCache#load does not get freed in any deterministic manner.

This stack trace shows YJP's idea of where the file handle was allocated, which also gives a fairly good testcase (org.eclipse.jgit.api.CloneCommand.call())


java.io.RandomAccessFile.<init>(File, String)
org.eclipse.jgit.internal.storage.file.PackFile.doOpen()
org.eclipse.jgit.internal.storage.file.PackFile.beginWindowCache()
org.eclipse.jgit.internal.storage.file.WindowCache.load(PackFile, long)
org.eclipse.jgit.internal.storage.file.WindowCache.getOrLoad(PackFile, long)
org.eclipse.jgit.internal.storage.file.WindowCache.get(PackFile, long)
org.eclipse.jgit.internal.storage.file.WindowCursor.pin(PackFile, long)
org.eclipse.jgit.internal.storage.file.WindowCursor.copy(PackFile,
long, byte[], int, int)
org.eclipse.jgit.internal.storage.file.PackFile.readFully(long,
byte[], int, int, WindowCursor)
org.eclipse.jgit.internal.storage.file.PackFile.load(WindowCursor, long)
org.eclipse.jgit.internal.storage.file.PackFile.get(WindowCursor, AnyObjectId)
org.eclipse.jgit.internal.storage.file.ObjectDirectory.openObject1(WindowCursor,
AnyObjectId)
org.eclipse.jgit.internal.storage.file.FileObjectDatabase.openObjectImpl1(WindowCursor,
AnyObjectId)
org.eclipse.jgit.internal.storage.file.FileObjectDatabase.openObject(WindowCursor,
AnyObjectId)
org.eclipse.jgit.internal.storage.file.WindowCursor.open(AnyObjectId, int)
org.eclipse.jgit.lib.ObjectReader.open(AnyObjectId)
org.eclipse.jgit.revwalk.RevWalk.parseAny(AnyObjectId)
org.eclipse.jgit.revwalk.RevWalk.parseCommit(AnyObjectId)
org.eclipse.jgit.api.CloneCommand.parseCommit(Repository, Ref)
org.eclipse.jgit.api.CloneCommand.checkout(Repository, FetchResult)
org.eclipse.jgit.api.CloneCommand.call()
org.apache.maven.scm.provider.git.jgit.command.checkout.JGitCheckOutCommand.executeCheckOutCommand(ScmProviderRepository,
Comment 1 Matthias Sohn CLA 2013-11-18 03:28:49 EST
Are you closing the repository after you're done cloning it ?
Comment 2 domi - CLA 2013-11-18 23:44:19 EST
We use the porcelan API in most of the places and did not grap the underlying repo of the "Git" object to close it. Anyway, I just did now [1] - but it did not help, still the same issue on windows.

I also had a look at the base class of the JGit testcase 'org.eclipse.jgit.api.CloneCommandTest' which is 'org.eclipse.jgit.junit.LocalDiskRepositoryTestCase' and this class seems to have quite some 'workarounds' to fix the same issues in the test cases - I guess I'll have to take a closer look at it. 

[1] https://github.com/imod/maven-scm/commit/598a90ea26cda92b6bbae4c8bf198d7176197d60
Comment 3 Christian Halstrick CLA 2013-11-19 07:48:55 EST
I suggest that we at least add a close() method to the Git class. User's of the JGit porcelain API should have the chance to close the repo without going too deep into low-level classes. See https://git.eclipse.org/r/#/c/18560
Comment 4 Matthias Sohn CLA 2013-11-19 18:56:50 EST
merged as 7dce16018e05c0a094b3eb20009e0438764f046e
Comment 5 domi - CLA 2013-11-24 08:47:18 EST
This issue can be closed, I found the origin problem in our code:

"Git.cloneRepository().call()" also returns an open repository, this was ignored and therefore also not closed.
We now reuse this instance and everything seems to be fine after closing it.

...the addition of the new Git.close() method is a nice clean addition - will make use of it in the future.
Comment 6 Matthias Sohn CLA 2013-11-26 03:31:08 EST
closing as domi verified this works