This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 100394 - IDE performance issue: scans all project files almost permanently
Summary: IDE performance issue: scans all project files almost permanently
Status: VERIFIED FIXED
Alias: None
Product: cnd
Classification: Unclassified
Component: Code Model (show other bugs)
Version: 5.x
Hardware: All All
: P1 blocker (vote)
Assignee: Thomas Preisler
URL:
Keywords: PERFORMANCE
Depends on:
Blocks:
 
Reported: 2007-04-09 21:23 UTC by Thomas Preisler
Modified: 2007-05-08 16:45 UTC (History)
10 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
request for notexisting file whose refresh took so much time (3.80 KB, text/plain)
2007-04-18 17:39 UTC, rmatous
Details
additional printings that help me to trap the above mentioned problem - against trunk version (4.63 KB, patch)
2007-04-18 18:28 UTC, rmatous
Details | Diff
masterfs.jar against 5.5.1 with additional printings (367.67 KB, application/octet-stream)
2007-04-19 16:41 UTC, rmatous
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Preisler 2007-04-09 21:23:17 UTC
Originally filed as CR 6538297.

DESCRIPTION OF PROBLEM
--------------------------------
I finally managed to import a large project into the IDE (about 2500 files,
including header files). Even with "Automatic Parsing Delay" set to zero, I
observe frequent bursts of file accesses, which seem to be triggered by trivial
user interactions like clicking in a window, scrolling the editor window etc. 
With truss, I can see that the IDE issues stat64 system calls on _every_ file in
the project (this lasts about 30 seconds for these 2500 files) at least every
two minutes, but sometimes even more frequently.
This places a significant burden on the machine where the IDE runs and (with NFS
mounted sources) also on the file server and on the network in general. IMO,
this is unnecessary: a IDE knows which files are open in the editor, and it need
not care about the other files. This should at least be restricted to the files
loaded in the editor.
STEPS TO REPRODUCE
-------------------------
Simply load a project  which consists of many files into the ide, then issue
"truss -t stat64 -p <pid_of_ide>" in some shell. Scroll through one or two
files, and observe the output of truss.
*** (#1 of 1): 2007-03-23 10:35:45
Comment 1 Vladimir Kvashin 2007-04-10 14:52:20 UTC
Investigation shows that this is a common NetBeans issue. The same happens with
Java projects: truss shows that stat64 is called frequently for each file in
project.

For now I don't know, which particular Netbeans component performs these calls.
Comment 2 _ rkubacki 2007-04-10 18:01:09 UTC
IMO this is filesystem refresh performed when main window of IDE is
(re)activated. I believe this must be a real problem with NFS mounts and then it
can last so long that it is hard to associate it with this cause.

Can you try DTrace's jstack to find appropriate Java call stack when stat64 is
called? This is a way how to confirm or find what piece of code trigers this
activity.
Comment 3 _ rkubacki 2007-04-12 09:46:52 UTC
------------------ forwarded mail from Jim Rice to Egor Ushakov -------------

Hi Egor - I took a look at the bug and ran NetBeans 5.5 using JEdit as an
example of a large project.

Once it was at a  steady state I kicked off the following script:

$ dtrace -n 'syscall::stat*:entry/execname == "java"/{@[jstack(50,8000)] =
count();} tick-300sec{trunc(@,50); exit(0);}'

It will run for 5 mins collecting stack traces (max 50 frames per trace) for
stat syscalls, called from java and outputs the top 50 on exit (I give jstack a
buffer of 8000 to avoid getting lots of dropped dtrace warnings and to give the
kernel enough space to name the name translations on the stack).

This produced plenty of output. The
org/netbeans/core/ui/warmup/MenuWarmUpTask$NbWindowsAdapter.run() seems to be
being called a lot of times and so I'd dig into this. I'm not sure who is making
all the  java/io/UnixFileSystem.getBooleanAttributes(), the stack is not giving
us any clues here.

            libc.so.1`stat64+0x15
            java/io/UnixFileSystem.getLastModifiedTime(Ljava/io/File;)J
            java/io/File.lastModified()J
           
org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObj.refresh(ZZ)V
           
org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObj.refresh(Z)V
           
org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectFactory.refreshAll(Z)V
           
org/netbeans/modules/masterfs/filebasedfs/FileBasedFileSystem.refresh(Z)V
            org/netbeans/modules/masterfs/MasterFileSystem.refresh(Z)V
            org/netbeans/core/ui/warmup/MenuWarmUpTask$NbWindowsAdapter.run()V
            org/openide/util/RequestProcessor$Task.run()V
            org/openide/util/RequestProcessor$Processor.run()V
            StubRoutines (1)
           
libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x1a3
           
libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_+0x27
           
libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x2f
           
libjvm.so`__1cJJavaCallsMcall_virtual6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4pnRJavaCallArguments_pnGThread__v_+0xc1
           
libjvm.so`__1cJJavaCallsMcall_virtual6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_5pnGThread__v_+0x7e
            libjvm.so`__1cMthread_entry6FpnKJavaThread_pnGThread__v_+0xd2
            libjvm.so`__1cKJavaThreadRthread_main_inner6M_v_+0x4c
            libjvm.so`__1cKJavaThreadDrun6M_v_+0x196
            libjvm.so`java_start+0xd3
            libc.so.1`_thr_setup+0x52
            libc.so.1`_lwp_start
           1019

            libc.so.1`stat64+0x15
            java/io/UnixFileSystem.getLastModifiedTime(Ljava/io/File;)J*
            java/io/File.lastModified()J
           
org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObj.refresh(ZZ)V
           
org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObj.refresh(Z)V
           
org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectFactory.refreshAll(Z)V
           
org/netbeans/modules/masterfs/filebasedfs/FileBasedFileSystem.refresh(Z)V
            org/netbeans/modules/masterfs/MasterFileSystem.refresh(Z)V
            org/netbeans/core/ui/warmup/MenuWarmUpTask$NbWindowsAdapter.run()V
            org/openide/util/RequestProcessor$Task.run()V
            org/openide/util/RequestProcessor$Processor.run()V
            StubRoutines (1)
           
libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x1a3
           
libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_+0x27
           
libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x2f
           
libjvm.so`__1cJJavaCallsMcall_virtual6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4pnRJavaCallArguments_pnGThread__v_+0xc1
           
libjvm.so`__1cJJavaCallsMcall_virtual6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_5pnGThread__v_+0x7e
            libjvm.so`__1cMthread_entry6FpnKJavaThread_pnGThread__v_+0xd2
            libjvm.so`__1cKJavaThreadRthread_main_inner6M_v_+0x4c
            libjvm.so`__1cKJavaThreadDrun6M_v_+0x196
            libjvm.so`java_start+0xd3
            libc.so.1`_thr_setup+0x52
            libc.so.1`_lwp_start
           1256

            libc.so.1`stat64+0x15
            java/io/UnixFileSystem.getLastModifiedTime(Ljava/io/File;)J
            java/io/File.lastModified()J
           
org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObj.refresh(ZZ)V
           
org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObj.refresh(Z)V
           
org/netbeans/modules/masterfs/filebasedfs/fileobjects/FolderObj.refresh(ZZ)V
           
org/netbeans/modules/masterfs/filebasedfs/fileobjects/FolderObj.refresh(Z)V
           
org/netbeans/modules/masterfs/filebasedfs/fileobjects/FileObjectFactory.refreshAll(Z)V
           
org/netbeans/modules/masterfs/filebasedfs/FileBasedFileSystem.refresh(Z)V
            org/netbeans/modules/masterfs/MasterFileSystem.refresh(Z)V
            org/netbeans/core/ui/warmup/MenuWarmUpTask$NbWindowsAdapter.run()V
            org/openide/util/RequestProcessor$Task.run()V
            org/openide/util/RequestProcessor$Processor.run()V
            StubRoutines (1)
           
libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x1a3
           
libjvm.so`__1cCosUos_exception_wrapper6FpFpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v2468_v_+0x27
           
libjvm.so`__1cJJavaCallsEcall6FpnJJavaValue_nMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x2f
           
libjvm.so`__1cJJavaCallsMcall_virtual6FpnJJavaValue_nLKlassHandle_nMsymbolHandle_4pnRJavaCallArguments_pnGThread__v_+0xc1
           
libjvm.so`__1cJJavaCallsMcall_virtual6FpnJJavaValue_nGHandle_nLKlassHandle_nMsymbolHandle_5pnGThread__v_+0x7e
            libjvm.so`__1cMthread_entry6FpnKJavaThread_pnGThread__v_+0xd2
            libjvm.so`__1cKJavaThreadRthread_main_inner6M_v_+0x4c
            libjvm.so`__1cKJavaThreadDrun6M_v_+0x196
            libjvm.so`java_start+0xd3
            libc.so.1`_thr_setup+0x52
            libc.so.1`_lwp_start
           1308

            libc.so.1`stat64+0x15
            java/io/UnixFileSystem.getBooleanAttributes0(Ljava/io/File;)I*
            java/io/UnixFileSystem.getBooleanAttributes(Ljava/io/File;)I*
            0xa0aff4f0
           2645

            libc.so.1`stat64+0x15
            java/io/UnixFileSystem.getBooleanAttributes0(Ljava/io/File;)I*
            java/io/UnixFileSystem.getBooleanAttributes(Ljava/io/File;)I*
            0xa0aff4f0
           4461
Comment 4 _ rkubacki 2007-04-12 09:51:39 UTC
Thanks to pasted output from dtrace it is confirmed now that these stat64 calls
are result of filesystem refresh performed when IDE window is activated.

Question: If we claim that all 2500 files belonging to a project are stat'ed why
do we need to hold fileobject for all of them?
Comment 5 rmatous 2007-04-12 10:02:33 UTC
To show refresh timne, number of alive fileobjects,...
-J-Dorg.netbeans.modules.masterfs.level=-1

Something like this should be printed out:
FS.refresh statistics (2015FileObjects):
  FileSystem refresh: 1 calls in 206ms
  Invocation of FileChangeListeners: 1 calls in 2ms
  Folder refresh: 1080 calls in 164ms
  File refresh: 1543 calls in 48ms

Comment 6 Antonin Nebuzelsky 2007-04-16 17:47:31 UTC
How frequent this issue is? Does this happen always when a project is placed on
NFS? Can it be caused by a special setup of NFS?

Can you run with the -J-Dorg.netbeans.modules.masterfs.level=-1 flag and attach
message.log?
Comment 7 Antonin Nebuzelsky 2007-04-16 17:47:41 UTC
How frequent this issue is? Does this happen always when a project is placed on
NFS? Can it be caused by a special setup of NFS?

Can you run with the -J-Dorg.netbeans.modules.masterfs.level=-1 flag and attach
messages.log?
Comment 8 julieg 2007-04-16 23:55:12 UTC
> How frequent this issue is? 
It happens whenever:
=> the CND parser is scanning
=> mouse clicking the directory/file in the Projects/Files pane
=> mouse clicking in the editor
=> scrolling up/down the editor
=> clicking the menu bar, then moving the mouse along the menu bar


> Does this happen always when a project is placed on NFS? 
No.  I can reproduce it locally without accessing NFS.
I installed NB+CND, boost project locally, and the compilers, make, 
user account are all located on the same machine.

> Can it be caused by a special setup of NFS?
Not in my investigation.

> Can you run with the -J-Dorg.netbeans.modules.masterfs.level=-1 flag
> and attach messages.log?
I did not find any new message after appending the -J option
Comment 9 julieg 2007-04-17 00:24:57 UTC
> How frequent this issue is? 
=> moving mouse in Projects/Files pane will also trigger it
Comment 10 julieg 2007-04-17 22:22:02 UTC
I tested this issue with NB 5.5.1 (without CND installed)
and still could reproduce it.
Comment 11 Jesse Grodnik 2007-04-18 16:27:03 UTC
This issue also applies to Linux (Ubuntu 6.x).

julieg ran the trace command:

strace -f -e trace=stat -p <pid>

and found the same problem as described in the IZ.
Comment 12 rmatous 2007-04-18 17:33:41 UTC
I spent a few hours and tried to investigate the problem, thus a few notes.

I found reproducible case when FS refresh is radically slower than in other
cases and which leads to 100% CPU. 
During refresh there were refreshed about 140 fileobjects on NFS whereas refresh
of every of 139 fileobjects took less than a milisecond but there was one that
took more than 10 seconds - all 10 seconds were spent in one call of
java.io.File.exist(). This very slow file was actually homeFolder "/home" that
was looking whether exist its child "nbproject"(see in attachment - that should
show who asked for "/home/nbproject"). At the same time automounter process
"/usr/sbin/automount --timeout=60 /home yp auto_home" took 100%CPU. 

Known Workaround:
Use symlink to address projects: e.g. so instead of
"/home/me/myprojects/myplugin" use "/tmp/me_symlink/myprojects/myplugin"

FS refresh mechanism: 
--------------------
FS refreshes all alive fileobjects (files, folders) in worker thread. Refreshing
folder means looking whether its cached children has changed. Folder instance
caches just those children that was already required by FS API clients - e.g.
folder.getFileObject("someChild") whereas following refresh will verify whether
"someChild" exist or not and then appropriately fires events if necessary. To
continue with the "someChild" example: folder.getFileObject("someChild") may
return null if "someChild" doesn't exists or maybe return non null instance of
FileObject - in any case "someChild" is cached - which means that refreshing
this instance of folder(until garbage collected including its caches) will care
of "someChild" because there should be guaranteed that after calling
folder.getFileObject("someChild") your FileChangeListener impl. will be notified
about external changes of "someChild".


AFAIK this behavior(keep in cache also requested childs that don't exists in the
moment) exists in NB since Sep 12 2006.


I don't know about similar problem on Windows, on Unix with locally placed
projects, userdir ..., on Unix with stopped automounter yet. If you know, please
investigate and let me know.
Comment 13 rmatous 2007-04-18 17:39:20 UTC
Created attachment 41186 [details]
request for notexisting file whose refresh took so much time
Comment 14 rmatous 2007-04-18 18:28:50 UTC
Created attachment 41188 [details]
additional printings that help me to trap the above mentioned problem - against trunk version
Comment 15 Petr Nejedly 2007-04-18 22:47:42 UTC
Note: In the original report, there were "all 2500 project files" stated.
This is most probably related to list-based nature of CND's projects and that
alone might be the source of the problem. It is reproducible even without NFS
according to one comment.
Comment 16 julieg 2007-04-18 23:01:15 UTC
I am able to reproduce this bug with NB 5.5.1 alone (without CND).
The NB IDE, JDK, & user account are all local.
Comment 17 rmatous 2007-04-19 13:04:42 UTC
=> the CND parser is scanning
=> mouse clicking the directory/file in the Projects/Files pane
=> mouse clicking in the editor
=> scrolling up/down the editor
Yes, files are really stat'ed - but not all 2500 files, not refresh of the whole
FS but because FS API clients from different modules from many different reasons
ask for children on folder, call method lastModified, or would like to know
mimeType, .... This shouldn't be reason for poor usability because only a few
files are touched (scrolling in editor touches mostly just the opened file).

=> clicking the menu bar, then moving the mouse along the menu bar
The same as above with one exception - which is SDI mode that triggers it FS
refresh whenever you touch menu, toolbar.

Generally FS refresh is called if explicitly invoked by FS API clients or
triggered when mainwindow is activated(or better 1500 ms after activation). This
post-activation refresh runs only one at the same time.

Thousands hard referenced FileObjects could really cause perf.problems during
refresh (especially in SDI mode that triggers it whenever you touch menu,
toolbar) and count to it also high memory consumption. Naturally it also play
role whether files are on your disk or on network.

Definitely FS refresh, the way how and when are files stat'ed didn't change
significantly since NB 5.0. There were a few changes like the one that causes 
the problem with automounter(NB since Sep 12 2006). 
Comment 18 rmatous 2007-04-19 16:41:53 UTC
Created attachment 41272 [details]
masterfs.jar against 5.5.1 with additional printings
Comment 19 rmatous 2007-04-19 16:43:50 UTC
I added ./nbbuild/netbeans/platform6/modules/org-netbeans-modules-masterfs.jar
with additional printing, please use for testing FS refreshes
Comment 20 Thomas Preisler 2007-04-24 07:32:10 UTC
CND is keeping large lists of fileobjects to support annotations on logical
folders. We could generate these list on demand (and not hang on to the
fileobejcts) but I took a second look at our UI model for annotation support and
are coming to the conclusion that we had created an inconsistency between what
annotations we displayed and what for instance the source control systems
supported. We were trying to base annotations on the exact list of files in a
project (some of them outside project root), but the version controls systems
work on directories so the annotations we displayed didn't always match what the
version control system thought and you would see badges for changed files and
nothing to check-in if you tried to list the changed files. To fully support the
project list model, the version control systems would also need to support a
list based model (similar to the changes we had added to Find). Perhaps we can
do this in 6.0.

To work-around all these problems, we have decided to simplify our UI model a
bit and don't annotate our logical folders. We will only annotate the project
folder (based on the project root directory) and all individual files (which is
handled by the file system, not by CND). By doing this all shown annotations
will be consistent with the versions control systems and we eliminate the need
for these large fileobject lists.

I will implement this (in CND) and also double-check that we don't keep other
lists of fileobjects around.
Comment 21 Thomas Preisler 2007-04-26 02:00:25 UTC
I didn't find any other places were we were holding on to large sets of
fileobjest so I consider this IZ fized (on our side).

The problems with lack of proper support for list based projects from clients
like the version control modules is still not fix and I may open a seperate issue. 
Comment 22 Alexander Pepin 2007-05-08 16:45:10 UTC
permanent file scanning is not discovered any more
verified in build 20070428