From: Kevin B. <kb...@ca...> - 2002-02-08 18:58:00
|
Very interesting. Looks like a definite bug in the garbage collector or assignment behavior, but I'm not conversant enough w/ the Java VM internals to pursue it further. I moved everything to Java then brought pieces back to Python, and found some interesting things. It only occurs if the assignment is in Python, and only if we allocate a new Jython Instance each time. Here's my output w/ -verbose:gc [GC 511K->143K(1984K), 0.0063209 secs] [GC 646K->154K(1984K), 0.0057092 secs] [GC 666K->334K(1984K), 0.0076847 secs] [GC 846K->609K(1984K), 0.0089791 secs] [GC 1121K->769K(1984K), 0.0077756 secs] [GC 1349K->972K(1984K), 0.0075615 secs] [GC 1484K->1017K(1984K), 0.0041208 secs] [GC 1529K->1529K(2112K), 0.0108365 secs] [Full GC 1529K->1256K(2112K), 0.1101383 secs] [GC 1768K->1768K(2672K), 0.0089964 secs] [GC 2280K->2280K(2800K), 0.0093338 secs] [Full GC[Unloading class sun.reflect.GeneratedMethodAccessor1] 2280K->2280K(2800K), 0.1113977 secs] [GC 2735K->2735K(4284K), 0.0495713 secs] [GC 3247K->3247K(4284K), 0.0097242 secs] [GC 3759K->3759K(4284K), 0.0100759 secs] [GC 4271K->4271K(4796K), 0.0101293 secs] [Full GC 4271K->4271K(4796K), 0.1363462 secs] [GC 4731K->4731K(7612K), 0.0557635 secs] [GC 5243K->5243K(7612K), 0.0109620 secs] [GC 5755K->5755K(7612K), 0.0101355 secs] [GC 6267K->6267K(7612K), 0.0105186 secs] [GC 6779K->6779K(7612K), 0.0099337 secs] [GC 7291K->7291K(7868K), 0.0099397 secs] [Full GC 7291K->7231K(7868K), 0.2444919 secs] [GC 8127K->8127K(13016K), 0.0159969 secs] [GC 9023K->9023K(13016K), 0.0183957 secs] [GC 9918K->9918K(13016K), 0.0185267 secs] [GC 10814K->10814K(13016K), 0.0156633 secs] [GC 11710K->11710K(13016K), 0.0180231 secs] [GC 12606K->12606K(13528K), 0.0179447 secs] [Full GC 12606K->12606K(13528K), 0.2222574 secs] [GC 14103K->14103K(22612K), 0.1005230 secs] [GC 15639K->15639K(22612K), 0.0282855 secs] [GC 17175K->17175K(22612K), 0.0373953 secs] [GC 18711K->18711K(22612K), 0.0282713 secs] [GC 20247K->20247K(22612K), 0.0307812 secs] [GC 21783K->21783K(23380K), 0.0296263 secs] [Full GC 21783K->21783K(23380K), 0.3246291 secs] [GC 24275K->24275K(39012K), 0.1485914 secs] [GC 26835K->26835K(39012K), 0.0468365 secs] 256 512 768 1024 1280 1536 1792 2048 2304 2560 2816 3072 3328 3584 3840 4096 4352 4608 4864 5120 5376 5632 5888 6144 6400 6656 6912 7168 7424 7680 7936 8192 8448 8704 8960 9216 9472 9728 9984 10240 10496 10752 [GC 29395K->28034K(39012K), 0.0413931 secs] 11008 11264 11520 11776 12032 12288 12544 12800 13056 13312 13568 13824 14080 14336 14592 14848 15104 15360 15616 15872 16128 16384 16640 16896 17152 17408 17664 17920 18176 18432 18688 18944 19200 19456 19712 19968 20224 20480 20736 20992 21248 21504 21760 22016 22272 22528 22784 23040 23296 23552 23808 24064 24320 24576 24832 25088 25344 25600 25856 26112 26368 26624 26880 27136 27392 27648 27904 28160 28416 28672 28928 29184 29440 29696 [GC Yes, the protection fault occurred just after writing '[GC' Here's the code (Crash.java): import org.python.util.PythonInterpreter; import org.python.core.*; import java.util.*; public class Crash { public Object data; public Crash(int n) { data=new byte[n]; } static PythonInterpreter cInterp = new PythonInterpreter(); static PyCode cCode = __builtin__.compile( "obj.data = newvalue", "<string>", "exec" ); static { cInterp.set( "newvalue", new Object() ); } // only crashes if DO_EACH and DO_PYTHON are both true static boolean DO_EACH = true; static boolean DO_PYTHON = true; public static void replace( Object o ) { cInterp.set( "obj", o ); if ( DO_EACH ) { cInterp.set( "newvalue", new Object() ); } if ( DO_PYTHON ) { cInterp.exec( cCode ); } else { ((Crash)o).data = new PyJavaInstance( new Object() ); } } public static void iterate( Collection c ) { Iterator i = c.iterator(); int n =0; while (i.hasNext()) { if ( (++n & 255) == 0 ) System.out.print( n + " " ); replace( i.next() ); } } public static Collection makeCollection( int n, int m ) { Collection c = new LinkedList(); for ( int i = 0; i < n; i++ ) { c.add( new Crash( m )); } return c; } public static void crash( int n, int m ) { iterate( makeCollection( n, m )); } public static void main(String []args) { int n = Integer.getInteger( "n", 100000 ).intValue(); int m = Integer.getInteger( "m", 222 ).intValue(); crash( n, m ); } } And here's the makefile: JDK=f:/j2sdk1.4 JAVAC=${JDK}/bin/javac JAVA=${JDK}/bin/java JYTHON=w:\tools\jython\jython.jar test2: Crash.class ${JAVA} -verbose:gc -classpath '${JYTHON};${CLASSPATH}' Crash Jeff, do you want to/did you enter a bug, or shall I? kb Jeff Emanuel wrote: > > Ok, here are the files inline: > > crash.py: > import java, Crash > > def makeContainer(n,m): > c=java.util.LinkedList() > for i in range(n): > c.add(Crash(m)) > return c > > def crash(it): > while it.hasNext(): > node = it.next() > node.data = java.lang.Object() > > if __name__=="__main__": > n=100000 > m=222 > container=makeContainer(n,m) > crash(container.iterator()) > > Crash.java: > public class Crash { > public Object data; > public Crash(int n) { > data=new byte[n]; > } > } > > Thanks for your interest. |