Bug 106202 - JavaModelCache should have configurable LRU cache limits
Summary: JavaModelCache should have configurable LRU cache limits
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 enhancement (vote)
Target Milestone: 3.1.1   Edit
Assignee: Jerome Lanneluc CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 106226 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-08-05 12:37 EDT by Ernest Pasour CLA
Modified: 2005-09-26 10:48 EDT (History)
2 users (show)

See Also:


Attachments
Patch to set the size of the caches relatively to the max heap size (2.73 KB, patch)
2005-08-18 11:03 EDT, Jerome Lanneluc CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ernest Pasour CLA 2005-08-05 12:37:19 EDT
We are working with the classpath container extension point and found that if we
add a lot of jars to our container, the JDT starts thrashing the garbage
collector.  Upon further investigation, we found that there is a limit of 2000
packages in the package cache in the JavaModelCache.  Every time I delete and
readd a semicolon and resave the file, the model cache appears to go rebuild the
cache data for all of those jars (even though I'm not actually referencing all
of them from my code) and this makes the garbage collector thrash.  Looking at
the code, it appears that 2000 is a hardcoded limit.  There is a setSpaceLimit()
method on LRUCache, but the class is internal, and I don't see a public way to
get the cache pointer anyway.  

So even though I'm running with -Xmx512m, I'm thrashing memory at a much lower
level than that, and I don't see a workaround other than to not add so many jars
to my classpath.
Comment 1 Jess Garms CLA 2005-08-05 13:40:45 EDT
We just ran into this same issue with a single very large (160MB) jar. Our
temporary fix was to double the size of the package cache directly in
JavaModelCache.java.

I see there being 3 possible long-term solutions to this:

1. Make the cache configurable via UI or commandline arguments.
   This is non-optimal in that people will have to know that this problem can
occur and how to fix it. Could possibly provide a warning somewhere that
thrashing was occurring, but still would be difficult to discover.

2. Size the cache relative to the size of the heap. 
   This is better, in that when a user experiences thrashing they are likely to
attempt increasing the heap size as a solution, as Ernest did.

3. Remove the package cache limit. 
   The comments for JavaModelCache indicate that a single package takes up 1782
bytes in memory. Is this truly accurate? Seems like this is larger than they
should actually be, as a PackageFragment appears (in my admittedly limited JDT
knowledge) to contain only a String[] and a reference to its parent. Maybe
PackageFragments don't need to be flushed from memory at all?
Comment 2 Olivier Thomann CLA 2005-08-07 22:10:20 EDT
*** Bug 106226 has been marked as a duplicate of this bug. ***
Comment 3 Philipe Mulet CLA 2005-08-11 11:39:07 EDT
We could still use the current heap size, which is evolving across the session.
Comment 4 Ernest Pasour CLA 2005-08-11 13:03:59 EDT
I think I prefer using the max heap size for an initial guess at a cache size
(overridable from the command line).  However, I believe the cache should grow
without limit if more space is needed.  If the cache size is *limited* to say 5%
of the max heap size, it's silly for me to have a lot of unused heap that I
can't get to.  I would prefer an aging strategy to get rid of cruft that is
probably no longer in use.

Also, I think that the number of classes available that need to be cached (i.e.
the size of the classpath) isn't necessarily related to working memory usage.  I
can take a project and double the size of the classpath without using more
workspace memory otherwise.  I believe that this lack of correlation makes it
unwise to impose a hard limit, even if user configurable.
Comment 5 Jerome Lanneluc CLA 2005-08-18 11:03:32 EDT
Created attachment 26232 [details]
Patch to set the size of the caches relatively to the max heap size

I first thought that it was not possible to get the max heap size
programmatically, but the 1.4 API Runtime#maxMemory() returns this max heap
size.

The attached patch sets the size of the JavaModel caches relatively to this max
heap size. If you start Eclipse with no argument, the default max heap size is
256MB, and the size of the caches remains unchanged. If you double the max heap
size (i.e. -XmX512M) the size of the JavaModel caches is doubled as well.
Comment 6 Jerome Lanneluc CLA 2005-08-18 11:09:59 EDT
(In reply to comment #4)
> I think I prefer using the max heap size for an initial guess at a cache size
> (overridable from the command line).  
The attached patch implements this.

> However, I believe the cache should grow without limit if more space is
> needed.  If the cache size is *limited* to say 5% of the max heap size, it's
> silly for me to have a lot of unused heap that I can't get to.  I would 
> prefer an aging strategy to get rid of cruft that is probably no longer in
> use.
That's an interresting idea, but this is a completely different direction than
the LRU cache stategy. Can you tell us more on how you would implement this
aging stategy ?

> Also, I think that the number of classes available that need to be cached 
> (i.e. the size of the classpath) isn't necessarily related to working memory
> usage.  I can take a project and double the size of the classpath without
> using more workspace memory otherwise.  I believe that this lack of
> correlation makes it unwise to impose a hard limit, even if user configurable.
Unfortunately, JDT Core might not be the only plugin in the system. If we didn't
limit the cache size, we would end up using all memory, leaving nothing for
other plugins.

Comment 7 Ernest Pasour CLA 2005-08-18 13:50:27 EDT
Well, I guess by aging strategy, I might do something like keep a timestamp on
the last cache access of each jar (I think you cache the class info with jar
granularity).  The cache size is unlimited, but if you haven't used cache info
from a jar within a certain time period (10 minutes, 1 hour, 1 day, etc.), then
the cache info corresponding to the jar can be dumped (immediately, on shutdown,
etc.).   You could use a thread to check periodically, or just check on
shutdown.  You can make this timeout value pretty short if you really want to
make sure they don't accumulate a lot of cache quickly by switching between
projects.

If the user is really using all of the cache info within the time window, then
they need all of that data in their cache working set.  If that amount of cache
(in conjunction with their other work) takes up too much of their heap, then
they need to increase their heap size.  The alternative is to thrash needlessly
when memory is available.
Comment 8 Philipe Mulet CLA 2005-09-01 05:22:05 EDT
This strategy would still need to be combined with a policy for avoiding memory
outage. Typically operations open lots of files within a fraction of a second...
so I would go first for what we have (improved to better use heap contextual
info), then from there consider a subsequent complimentary strategy.
Comment 9 Philipe Mulet CLA 2005-09-01 06:04:09 EDT
+1 for 3.1.1, if we get positive feedback from APT scenario. If not, there is no
strong need to push this into a 3.1 update.
Jess - can you sync with Jerome to see if this would meet your needs ?
Comment 10 Jess Garms CLA 2005-09-01 13:39:39 EDT
The patch looks good. If we set our max heap to 512M, we can put our large jar
on the classpath and still get reasonable performance. Agree this would be great
to have in 3.1.1.
Comment 11 Jerome Lanneluc CLA 2005-09-02 08:40:46 EDT
Thanks Jess.

Released patch in both HEAD and R3_1_maintenace branch.

Ernest, so as to not loose your idea of aging stategy I opened bug 108665. Feel
free to add yourself to the CC list to get informed of its progress.
Comment 12 David Audel CLA 2005-09-21 09:41:33 EDT
Verified in I20050920-0010 for 3.2M2
Comment 13 Olivier Thomann CLA 2005-09-26 10:48:46 EDT
Verified for 3.1.1 using M20050923-1430.