Good performance from Method.invoke() is very important for many reflective applications. In previous versions of libgcj security checks were not perfomed, and our performance was only a little worse than the JRE. A recent patch added security checks and now: - Method.invoke is now ~10 x slower than the JRE - Method.invoke leaks memory every time it is called Clearly there are some simple optimizations that can be made - security check is not needed if method is public or accessibility flag is true. Ideally however the security check implementation itself should be made much faster. Test case w/ timers follows. import java.lang.reflect.*; public class RefTest2 { static int i = 0; public int increment(int value) { return ++i; } public static void main(String[] args) throws Exception { Method method = RefTest2.class.getMethod ("increment", new Class [] { int.class }); Object[] arg = new Object[1]; Object value = new Integer(0); RefTest2 testObj = new RefTest2(); while (true) { long startTime = System.currentTimeMillis(); for (int i = 0; i < 1000000; i++) { arg[0] = value; value = method.invoke(testObj, arg); } System.out.println (System.currentTimeMillis() - startTime + " ms"); } } }
I can confirm the slowness on the mainline (20030802) on powerpc-apple-darwin6.6 but I do not see any leaks.
Interesting - the test case consumes all available memory on my 512MB RHL 9 x86 after around 20M calls. Perhaps the leak is in system-dependent unwinder code.
I see the memory leak on i686-pc-linuc-gnu also.
Subject: Bug 11780 CVSROOT: /cvs/gcc Module name: gcc Changes by: bryce@gcc.gnu.org 2003-10-25 06:49:20 Modified files: libjava : ChangeLog libjava/java/lang/reflect: natMethod.cc natField.cc Log message: PR libgcj/11780: * java/lang/reflect/natMethod.cc (invoke): Look up caller and perform accessibility check only if target is non-public and accessible flag is not set. * java/lang/reflect/natField.cc (getAddr): Likewise. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/ChangeLog.diff?cvsroot=gcc&r1=1.2295&r2=1.2296 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/java/lang/reflect/natMethod.cc.diff?cvsroot=gcc&r1=1.33&r2=1.34 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/java/lang/reflect/natField.cc.diff?cvsroot=gcc&r1=1.14&r2=1.15
It still is slow: tin:~/src/gnu/gcctest>gij RefTest2 1574 ms 1596 ms tin:~/src/gnu/gcctest>java RefTest2 335 ms 271 ms But this no longer leaks so update summary.
Things look even worse with svn head (4.2 atm)... either with gij or precompiled, the test case shows invocations about an order of magnitude slower than the JDK.
With a public call, as in the current test case, it is "only" about 2.5X slower than HotSpot for me: $ ./a.out public call: 499 ms private call: 7344 ms $ java RefTest3 public call: 182 ms private call: 808 ms Private calls show a larger difference due to the requirement for an accessibility check, which involves stack inspection.
Created attachment 11156 [details] Test Case New version of the test case, which tests both public and private method invocation.
Closing as won't fix as libgcj (and the java front-end) has been removed from the trunk.