Community
Participate
Working Groups
Build 20020214 In newsgroup post "eclipse performance" by Ulrich Schreiner <ulrich.schreiner@innuendo.de>, he observes that the filesystem is accessed quite often, even when simply clicking around in the packages view, or toggling library visibility. This is problematic when the workspace is on a network. (It would also be noticeable on a laptop which needs to spin up its drive each time). For the library filtering case, JavaProject.getAllPackageFragmentRoots() causes JavaModel.getTarget(...) to be called several times with checkResourceExistence==true, causing File.exists() to be called on each library several times. It's not just getAllPackageFragmentRoots() that causes this. Try setting a breakpoint in JavaModel.getTarget on the line with externalFile.exists() and try clicking around in the packages view, clicking on a library, creating new packages, types, etc. Or, more low level, set a breakpoint on File.exists(). Ideally JDT should not have to access the filesystem at all unless reading or saving files (including indexing, building, code assist, etc.). I'm filing this against JDT UI since, although JavaModel is in Core, it might have to do with the way Core is being called from the UI. The original post is: Ulrich, This is very interesting. One of the main priorities for 2.0 is performance improvement, so this kind of feedback is very helpful. The granularity of loading is usually a class though, not a whole Jar at a time, so it's normal for a Java VM to keep going back to the same jar file, but it should be for a different .class file each time. You can see this by running with the -verbose VM arg. So the case you describe still sounds strange. Once you've toggled visibility of libraries off and back on, it should no longer be loading classes. I'm looking into it... Nick "Ulrich Schreiner" <ulrich.schreiner@innuendo.de> wrote in message news:a5dr89$jo$1@rogue.oti.com... > hi, > > we installed eclipse on a network drive. to start eclipse we also have a > batch-file which sets the workspace directory to a subdirectory on the users > home network drive. > > the jdk1.4 is also installed on the global network drive and the eclipse > batch uses the "-vm" option to use this network jdk. > > now it is possible to log in on every workstation and work with eclipse. you > always have your own workspace directory. another big advantage is that i > can backup every persons workspace directory every night. > > to support external libraries we have a classpath variable named "LIB_HOME" > which also points to a network directory in which we have external > libraries. so we can version projects and work at home as long as you > replicate the LIB_HOME directory from time to time. > > everythin works, everythin would be fine, but: > > we have a performance problem. i used a network sniffer and realized that a > simple mouseclick in my packagetree lead to a SMB network call to our > samba-server to load some external libraries. i set "-vmargs -Xnoclassgc" in > our batch file so that the java vm won't gc the classes. i thought that > after some working there would be no need to reload the jars again and > again. > > but it is not so. they are loaded very very often. again and again. > > another interesting point is the "show referenced libraries" menu entry. by > toggling this entry you see that a single library is loaded very often. it > seems it is loaded for every project it is referenced. and i think every > required project is also traversed. > > perhaps i'm wrong but in my case i have one project "Tomcat401" which > references all tomcat 401 libraries (jar's). every other project which is a > webapp simply has this project in its dependencies because i need the TC > classes at runtime (not at compile time). > > when i set the "show referenced libraries" to "true", the sniffer shows that > every jar is loaded about 3-5 times or more. and the project has 25 JAR's!!! > > this leads to dramatic network traffic which i think is the problem of the > performance leak. after installing everything on a local machine everything > works much better. but in this case i have the big problem of administrating > the installation. > > has anyone the same problem? are there any settings in eclipse or in the jdk > that can be used for runtime caching? > > help would be great > > thx > > Ulrich Schreiner
Is this related to bug 6867? Hopefully we can get this fixed.
JDT has to access the filesystem for all external JAR given the platform doesn't give us any support there. Checking for file existency is the way the JavaModel reacts to external JARs being discovered at some point. Now, we might be asking the question too often.
I've checked the UI the traces that end up calling JavaModel.getTarget look reasonable. There are several calls to IJavaElement.exists, but they look OK to me and I don't see how can avoid them. For example, when computing error ticks we guard the code with an IJavaElement.exists call. One place where I discoved a call to JavaProject.getAllPackageFragmentRoots() is related to showing the outline for a type inside an external JAR. To show the override indicator a type hierarchy is computed and it has the side effect of calling getAllPackageFragmentRoots. moving to JDT CORE
It seems like to show error ticks, you should not care whether the Jar exists or not, just whether it has errors or not. This info should be maintained by the Java model. If the Java model has no errors for the jar, you don't need to check its existence. The same approach might be possible elsewhere, to avoid exists checks until they are really necessary (e.g. doing a build or code assist).
The JavaModel only produces elements which are existing, as opposed to manually created handles. Thus, there shouldn't be any need for an existency check for error ticking (given the model is reconciled each time a change occurs). In order to solve external JARs correctly, we would need a callback from UI to tell us to refresh the model with respect to change external JARs. We currently rely on existency checks to capture situations where the JAR got deleted under us (we force a refresh each time a build occurs, as a workaround).
>Thus, there shouldn't be any need for an existency check for >error ticking (given the model is reconciled each time a change occurs). not really, error ticks are also shown in non-reconciled views like the type hierarchy view or the packages view. We can eliminat the exists call in the error tick computation for elements inside external JARs. This solves this particular case. However, there are many other exists() call in our code (notice that the API doesn't mention that this is an expensive call) so I doubt that this solves the problem in general (i.e., an exists call results in fetching the contents of an entire JAR). We should investigate in making the exists call cheaper. In addition how do we explain the following observations reported in the PR: 1) a simple mouseclick in my packagetree lead to a SMB network call to our samba-server to load some external libraries 2) toggling "show referenced libraries" you see that a single library is loaded very often. it seems it is loaded for every project it is referenced. and i think every required project is also traversed.
I was able to reproduce both of these cases. If you click on a type in the packages view, it's not a problem, but if you click on an external library, it does an exists check. Toggling library visibility also does several exists checks. They have a large number of libraries, so the effect is multiplied.
Fixed bug 10378 which fixes the existence check problem. However we still create too many ZipFile instances (which access the file system).
Moving this one to JDT/UI, since we have http://dev.eclipse.org/bugs/show_bug.cgi?id=10378 describing the same issue on the JDT/Core side. There are likely opportunities for JDT/UI to avoid calling expensinve existency checks and so on.
The critical issues got addressed. No further action is planned on this problem.