The excerpt below from an email from a customer (see the Comments section for details) indicates a performance problem with Cipher.getInstance() the first time it is run after rebooting a Windows system. Apparently it is calling File.list() in java.io.tmpdir, which at a high level seems unnecessary and causes major performance issues on machines with a large number of files in the system's temporary directory. See the attachment for a test case from the customer.
If investigation indicates that this is a problem in the deployment technologies or the extension class loader, please indicate this and we can reassign the bug to the appropriate team.
About two weeks ago I was informed that some of our machines were pausing for an extended period of time partway through start up of our applets. The startup delay appeared to be specific to certain machines and to the first use of our applets after system boot. I investigated (luckily one of the machines affected was my own!) and what I discovered was that the initial call to ???Cipher.getInstance()??? was taking upto 30 seconds to complete. Subsequent calls to Cipher.getInstance() were fractions of a millisecond. I examined stack traces taken during the pause and determined that the system was busy doing a File.list() call.
It appears that during the loading of lib/ext/sunjce_provider.jar a File.list() is executed against the java.io.tmpdir. On Windows XP this property references the user???s ???Local Settings\Temp\??? directory. Since this directory is used as a dumping ground for numerous applications is contents are unpredictable. What I discovered on my machine was that it contained 11000+ files.
I tried doing a dos-level listing on that directory just after a boot and found that just listing the files was taking about 30 seconds.
To further confirm the problem I wrote some functions that I have attached. The test program wraps three behaviors
1) adding 50,000 files to a temp directory.
2) measuring the time it takes to List and FileList(fileFilter) those files,
3) measure the time it takes to run Cipher.getInstance().
(Sorry, didn???t write any cleanup code to remove the files.)
I also set up the functions so that an alternate directory could be specified to java.io.tmpdir at run time. There are batch files included to exercise each behavior.
The results of running these tests follow:
at boot with 50000 files - 101207.88 ms
post boot with 50000 files ??? 678 ms
at boot with no files ??? 902 ms
post boot with no files - 350 ms
at boot with 50000 files ??? 104264.64 ms
post boot with 50000 files ??? 209 ms
I have put a workaround into our code to add a java-specific directory to the standard java.io.tmpdir path and that fixes the problem for our signed jars. The same approach won???t work for unsigned jars.
Although this only happens at first use after bootup, it is a significant and unexpected performance hit. I don???t know whether the File.list() function is needed as part of the ext jar loading procedure since I don???t have access to this code, but it might seem to be a good idea, in general, to have the java.io.tmpdir point to a directory that was not as prone to filling with ???foreign??? files.