问题
While debugging slow startup of an Eclipse RCP app on a Citrix server, I came to find out that java.io.createTempFile(String,String,File) is taking 5 seconds. It does this only on the first execution and only for certain user accounts. Specifically, I am noticing it Citrix anonymous user accounts. I have not tried many other types of accounts, but this behavior is not exhibited with an administrator account.
Also, it does not matter if the user has access to write to the given directory or not. If the user does not have access, the call will take 5 seconds to fail. If they do have access, the call with take 5 seconds to succeed.
This is on a Windows 2003 Server. I've tried Sun's 1.6.0_16 and 1.6.0_19 JREs and see the same behavior.
I googled a bit expecting this to be some sort of known issue, but didn't find anything. It seems like someone else would have had to have run into this before.
The Eclipse Platform uses File.createTempFile() to test various directories to see if they are writeable during initialization and this issue adds 5 seconds to the startup time of our application.
I imagine somebody has run into this before and might have some insight. Here is sample code I executed to see that it is indeed this call that is consuming the time. I also tried it with a second call to createTempFile and notice that subsequent calls return nearly instantaneously.
public static void main(final String[] args) throws IOException { final File directory = new File(args[0]); final long startTime = System.currentTimeMillis(); File file = null; try { file = File.createTempFile("prefix", "suffix", directory); System.out.println(file.getAbsolutePath()); } finally { System.out.println(System.currentTimeMillis() - startTime); if (file != null) { file.delete(); } } }
Sample output of this program is the following:
C:\>java.exe -jar filetest.jar C:/Temp C:\Temp\prefix8098550723198856667suffix 5093
回答1:
It might be the intialisation of the secure random number generator which is causing the problem. In particular if a secure random seed is not obtainable from the operating system, then the fall-back mechanism attempts to gain entropy. IIRC, one of the things it does is to list temporary files, so if you have a large number of those that will not help start-up performance.
回答2:
It looks like the slowness is due to the seeding of SecureRandom and only when the user is a member of the Guests group.
The SecureRandom seed initialization uses a Windows Crypto API which fails when the user is a guest as described here [1]. By setting the system property "java.security.debug" equal to "all", I can see the following when the program as run as a guest:
ProviderConfig: Loaded provider SUN version 1.6 provider: Failed to use operating system seed generator: java.io.IOException: Required native CryptoAPI features not available on this machine provider: Using default threaded seed generator
When run as non-guest user, the output is this:
ProviderConfig: Loaded provider SUN version 1.6 provider: Using operating system seed generator
It appears the default threaded seed generator is quite slow. Here [2] is a very old bug logged to Sun about this.
[1] http://www.derkeiler.com/Newsgroups/microsoft.public.platformsdk.security/2003-12/0349.html
[2] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4210047
回答3:
I'm not a Citrix expert, but I know someone who is, and who conjectures:
The accounts may be set up so that application reads/writes are redirected to non-local resources. The latency you're experiencing may be related to the initialization or performance of that resolution.
Another possibility is that the application isolation may be in effect, which means file reads/writes happen on virtualized versions of resources.
来源:https://stackoverflow.com/questions/2608763/why-does-first-call-to-java-io-file-createtempfilestring-string-file-take-5-se