问题
I have about 55 Java interfaces and 5 abstract classes. Each declaration uses the same set of generic parameters: it lists the approximately 60 declarations so each implementation knows a specific type of each other implementation and substitute this type in method parameters and returns as appropriate. It appears that this (perhaps over)use of generics is causing the compiler to hang. The compiler throws an OutOfMemoryError, but does not appear to terminate.
Considering my circumstance, a code listing comprising even one of these declarations is a little difficult, but a part of a listing might be possible. The interface declarations commonly specify a collection of about five methods, but the use of generics in the declaration increases the size of a source module to about a thousand lines.
Could my case be a case of the compiler actually going into an infinite loop, or should I just give it more memory? It takes about 20 minutes for the OutOfMemoryError exception to be thrown, so I'm concerned that if I just increase the memory given to the compiler by a factor, it will just take that factor longer for the compiler to throw the exception.
I'm using NetBeans as my editor environment, but have been resorting to running the clean/build script as soon as I start NetBeans. I do this because NetBeans quickly becomes unresponsive when it begins to check the syntax of my code after start-up. I'm using Ubuntu 10.4 (I think - I'm writing this from Windows). I have resorted to opening a command line in the Ubuntu environment, running NetBeans as a background process, checking the output and correcting any source code mistakes using gedit, killing and then restarting NetBeans. This appeared to suffice until I found that no more syntax errors were being produced. I don't know how to run the clean/build script from the command line.
Sorry if this question appears vague, but if others could help me then maybe I could be a little more specific.
Thanks for any considered advice.
回答1:
It sounds to me like you've got some overly complicated use of generics, and this is causing the Java compiler to use an excessive amount of memory trying to represent the expansions of the generic types. The very long times before failure are probably due to a "garbage collection death spiral" ... where the GC spends more and more time, reclaiming less and less memory each time, until it finally has to give up.
If you can't show us the code, the only possible suggestion is to run the compiler with a larger heap, and see if that cures the problem.
I don't know how to run the clean/build script from the command line.
Well, I think you need to figure that out. It may help you solve the problem, and it is important to know these things anyway; e.g. so that you can use a CI system to build your code and run your tests. (And you will probably need to run the script from the command line to get the build to run in a separate JVM with a heap whose size you can control independently of your IDE.)
It is also possible that your complicated use of generics includes something pathological (and probably nonsensical) that the Java compiler cannot cope with.
A probable source of trouble about my generic declarations is that they're self referential; one declaration refers to another which refers to the first.
Yea ... that's the kind of thing that I'm talking about. If you are not careful, you can end up with something that is meaningless (from a Java perspective) that involves infinite type expansions.
来源:https://stackoverflow.com/questions/14115597/use-of-java-generics-could-be-hanging-the-compiler