This is the mail archive of the java-patches@sourceware.cygnus.com mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch: Bitmap descriptor GC marking


Here's my patch that tries to implement bitmap based GC marking. I'm
posting it in the hope that someone who knows more about the collector
than I do can figure out why it doesnt work right ;-)

The problems, as far as I can tell, are that if GC_GCJ_MALLOC() is used:

- the heap in some cases grows much bigger than usual when using arrays.

- finialization doesn't seem to work at all.

I've also attached a "GCTest" which shows the problems. A "normal"
GCTest run should look something like this:

$ ./gctest
smallArrays() : .......... 6048ms  (heap: total=18276K free=6392K)
bigArrays()   : .......... 8455ms  (heap: total=20324K free=10428K)
objArray()    : .......... 8471ms  (heap: total=22372K free=7532K)
finalization(): .......... [900000]  9522ms  (heap: total=22372K
free=5148K)

but a run using this patch looks like this:

$ ./gctest
smallArrays() : .......... 8655ms  (heap: total=18276K free=6396K)
bigArrays()   : .......... 46094ms  (heap: total=63420K free=17804K)
objArray()    : .......... 11250ms  (heap: total=63420K free=44388K)
finalization(): .......... [0]  3149ms  (heap: total=63420K free=53284K)

(the second run is slower because its a debug build. Note the heap
growth and the lack of finalization.)

I've been kicking this patch around for a while - earlier versions also
did things like change the array and vtable allocations and inline the
array allocation functions. This is an attempt to create a minimal patch
to try and isolate the problems before moving on.

regards

  [ bryce ]

2000-05-07  Bryce McKinlay  <bryce@albatross.co.nz>

	* Makefile.am: Build gcj_mlc.c.
	* Makefile.in: Updated.
	* configure.in: Define GC_GCJ_SUPPORT.
	* configure: Updated.
	
2000-05-07  Bryce McKinlay  <bryce@albatross.co.nz>

	* configure.in: Define JC1GCSPEC. Set it if boehm-gc is used.
	* configure: Updated.
	* libgcj.spec.in: Pass JC1GCSPEC to jc1.
	* boehm.cc: Include gc_gcj.h.
	(_Jv_AllocObj): New parameter `klass'. Use GC_GCJ_MALLOC ().
	(_Jv_AllocArray): New parameter `klass'. Set vtable pointer of new
	object before returning.
	(_Jv_InitGC): Call GC_init_gcj_malloc (). Don't set up marking and
	allocation for obj_kind_x.
	* prims.cc (_Jv_AllocObject): Rename parameter `c' to `klass'. Pass
	`klass' to _Jv_AllocObj. Don't set the new object's vtable.
	(_Jv_NewObjectArray): Rename parameter `clas' to `klass'. Pass
	`klass' to _Jv_AllocArray. Don't set the new array's vtable.
	(_Jv_NewPrimArray): Call _Jv_FindArrayClass before _Jv_AllocObj. Pass
	`klass' to _Jv_AllocObj. Don't set the new array's vtable.
	* include/jvm.h (struct _Jv_VTable): New field `gc_descr'.
	(_Jv_AllocObj): Declare new jclass parameter.
	(_Jv_AllocArray): Ditto.
	* java/lang/Class.h (_Jv_NewObjectArray): No longer a friend.
	(_Jv_NewPrimArray): Ditto.
	(_Jv_AllocObj): Declare as a friend.
	(_Jv_AllocArray): Ditto.
	* java/lang/natClassLoader.cc (_Jv_FindArrayClass): Copy marking
	descriptor from &ObjectClass into new array class.

Index: boehm-gc/Makefile.am
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/Makefile.am,v
retrieving revision 1.15
diff -u -r1.15 Makefile.am
--- Makefile.am	2000/04/19 12:47:53	1.15
+++ Makefile.am	2000/05/07 08:44:48
@@ -27,7 +27,7 @@
 EXTRA_LTLIBRARIES = libgcjgc.la
 libgcjgc_la_SOURCES = allchblk.c alloc.c blacklst.c checksums.c	\
 gcconfig.h dbg_mlc.c dyn_load.c finalize.c gc.h gc_alloc.h gc_cpp.h \
-gc_hdrs.h gc_mark.h gc_priv.h gc_private.h gc_typed.h headers.c	\
+gc_hdrs.h gc_mark.h gc_priv.h gc_private.h gc_typed.h gcj_mlc.c headers.c \
 hpux_irix_threads.c linux_threads.c malloc.c mallocx.c mark.c mark_rts.c \
 misc.c new_hblk.c obj_map.c os_dep.c pcr_interface.c ptr_chck.c	\
 real_malloc.c reclaim.c solaris_pthreads.c solaris_threads.c \
Index: boehm-gc/Makefile.in
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/Makefile.in,v
retrieving revision 1.18
diff -u -r1.18 Makefile.in
--- Makefile.in	2000/04/27 00:43:33	1.18
+++ Makefile.in	2000/05/07 08:44:50
@@ -108,7 +108,7 @@
 EXTRA_LTLIBRARIES = libgcjgc.la
 libgcjgc_la_SOURCES = allchblk.c alloc.c blacklst.c checksums.c	\
 gcconfig.h dbg_mlc.c dyn_load.c finalize.c gc.h gc_alloc.h gc_cpp.h \
-gc_hdrs.h gc_mark.h gc_priv.h gc_private.h gc_typed.h headers.c	\
+gc_hdrs.h gc_mark.h gc_priv.h gc_private.h gc_typed.h gcj_mlc.c headers.c \
 hpux_irix_threads.c linux_threads.c malloc.c mallocx.c mark.c mark_rts.c \
 misc.c new_hblk.c obj_map.c os_dep.c pcr_interface.c ptr_chck.c	\
 real_malloc.c reclaim.c solaris_pthreads.c solaris_threads.c \
@@ -197,7 +197,7 @@
 LDFLAGS = @LDFLAGS@
 LIBS = @LIBS@
 libgcjgc_la_OBJECTS =  allchblk.lo alloc.lo blacklst.lo checksums.lo \
-dbg_mlc.lo dyn_load.lo finalize.lo headers.lo hpux_irix_threads.lo \
+dbg_mlc.lo dyn_load.lo finalize.lo gcj_mlc.lo headers.lo hpux_irix_threads.lo \
 linux_threads.lo malloc.lo mallocx.lo mark.lo mark_rts.lo misc.lo \
 new_hblk.lo obj_map.lo os_dep.lo pcr_interface.lo ptr_chck.lo \
 real_malloc.lo reclaim.lo solaris_pthreads.lo solaris_threads.lo \
Index: boehm-gc/configure
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/configure,v
retrieving revision 1.21
diff -u -r1.21 configure
--- configure	2000/04/27 00:43:33	1.21
+++ configure	2000/05/07 08:45:54
@@ -2258,6 +2258,9 @@
 #define JAVA_FINALIZATION 1
 EOF
 
+cat >> confdefs.h <<\EOF
+#define GC_GCJ_SUPPORT 1
+EOF
 
 if test -n "${with_cross_host}"; then
    cat >> confdefs.h <<\EOF
Index: boehm-gc/configure.in
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/configure.in,v
retrieving revision 1.17
diff -u -r1.17 configure.in
--- configure.in	2000/04/19 10:09:57	1.17
+++ configure.in	2000/05/07 08:45:54
@@ -191,6 +191,7 @@
 AC_DEFINE(NO_SIGNALS)
 AC_DEFINE(NO_DEBUGGING)
 AC_DEFINE(JAVA_FINALIZATION)
+AC_DEFINE(GC_GCJ_SUPPORT)
 
 dnl This is something of a hack.  When cross-compiling we turn off
 dnl some functionality.  We also enable the "small" configuration.
Index: libjava/boehm.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/boehm.cc,v
retrieving revision 1.20
diff -u -r1.20 boehm.cc
--- boehm.cc	2000/05/06 23:32:52	1.20
+++ boehm.cc	2000/05/07 08:45:54
@@ -28,6 +28,7 @@
 {
 #include <gc_priv.h>
 #include <gc_mark.h>
+#include <include/gc_gcj.h>
 
   // These aren't declared in any Boehm GC header.
   void GC_finalize_all (void);
@@ -295,22 +296,21 @@
   return mark_stack_ptr;
 }
 
-// Allocate space for a new Java object.  FIXME: this might be the
-// wrong interface; we might prefer to pass in the object type as
-// well.  It isn't important for this collector, but it might be for
-// other collectors.
+// Allocate space for a new Java object.
 void *
-_Jv_AllocObj (jsize size)
+_Jv_AllocObj (jsize size, jclass klass)
 {
-  return GC_GENERIC_MALLOC (size, obj_kind_x);
+  return GC_GCJ_MALLOC (size, klass->vtable);
 }
 
-// Allocate space for a new Java array.  FIXME: again, this might be
-// the wrong interface.
+// Allocate space for a new Java array.
 void *
-_Jv_AllocArray (jsize size)
+_Jv_AllocArray (jsize size, jclass klass)
 {
-  return GC_GENERIC_MALLOC (size, array_kind_x);
+  ptr_t obj = GC_GENERIC_MALLOC (size, array_kind_x);
+  *((_Jv_VTable **) obj) = klass->vtable;
+  return obj;
 }
 
 // Allocate some space that is known to be pointer-free.
@@ -423,7 +423,57 @@
       return;
     }
   initialized = 1;
+  UNLOCK ();
+
+  // Configure the collector to use the bitmap marking descriptors that we
+  // stash in the class vtable.
+  GC_init_gcj_malloc (0, (void *) _Jv_MarkObj);  
+
+  LOCK ();
+  GC_java_finalization = 1;
+
+  // We use a different mark procedure for object arrays. This code 
+  // configures a different object `kind' for object array allocation and
+  // marking.
+  array_free_list = (ptr_t *) GC_generic_malloc_inner ((MAXOBJSZ + 1)
+						       * sizeof (ptr_t),
+						       PTRFREE);
+  memset (array_free_list, 0, (MAXOBJSZ + 1) * sizeof (ptr_t));
+
+  proc = GC_n_mark_procs++;
+  GC_mark_procs[proc] = (mark_proc) _Jv_MarkArray;
+
+  array_kind_x = GC_n_kinds++;
+  GC_obj_kinds[array_kind_x].ok_freelist = array_free_list;
+  GC_obj_kinds[array_kind_x].ok_reclaim_list = 0;
+  GC_obj_kinds[array_kind_x].ok_descriptor = MAKE_PROC (proc, 0);
+  GC_obj_kinds[array_kind_x].ok_relocate_descr = FALSE;
+  GC_obj_kinds[array_kind_x].ok_init = TRUE;
+
+  _Jv_MutexInit (&disable_gc_mutex);
 
+  UNLOCK ();
+  ENABLE_SIGNALS ();
+}
+
+#if 0
+void
+_Jv_InitGC (void)
+{
+  int proc;
+  DCL_LOCK_STATE;
+
+  DISABLE_SIGNALS ();
+  LOCK ();
+
+  if (initialized)
+    {
+      UNLOCK ();
+      ENABLE_SIGNALS ();
+      return;
+    }
+  initialized = 1;
+
   GC_java_finalization = 1;
 
   // Set up state for marking and allocation of Java objects.
@@ -464,3 +514,4 @@
   UNLOCK ();
   ENABLE_SIGNALS ();
 }
+#endif
Index: libjava/configure
===================================================================
RCS file: /cvs/java/libgcj/libjava/configure,v
retrieving revision 1.58
diff -u -r1.58 configure
--- configure	2000/04/21 20:46:10	1.58
+++ configure	2000/05/07 08:46:17
@@ -2467,6 +2467,7 @@
 GCDEPS=
 GCOBJS=
 GCSPEC=
+JC1GCSPEC=
 GCTESTSPEC=
 case "$GC" in
  boehm)
@@ -2477,6 +2478,7 @@
     GCLIBS="$GCDEPS -L\$(here)/../boehm-gc/$libsubdir"
     GCINCS='-I$(top_srcdir)/../boehm-gc -I$(top_builddir)/../boehm-gc'
     GCSPEC='-lgcjgc'
+    JC1GCSPEC='-fuse-boehm-gc'
     GCTESTSPEC="-L`pwd`/../boehm-gc/.libs -rpath `pwd`/../boehm-gc/.libs"
             GCINCS="$GCINCS `cat ../boehm-gc/boehm-cflags`"
     GCOBJS=boehm.lo
@@ -5339,6 +5341,7 @@
 s%@GCDEPS@%$GCDEPS%g
 s%@GCOBJS@%$GCOBJS%g
 s%@GCSPEC@%$GCSPEC%g
+s%@JC1GCSPEC@%$JC1GCSPEC%g
 s%@GCTESTSPEC@%$GCTESTSPEC%g
 s%@THREADLIBS@%$THREADLIBS%g
 s%@THREADINCS@%$THREADINCS%g
Index: libjava/configure.in
===================================================================
RCS file: /cvs/java/libgcj/libjava/configure.in,v
retrieving revision 1.57
diff -u -r1.57 configure.in
--- configure.in	2000/04/21 20:46:11	1.57
+++ configure.in	2000/05/07 08:46:20
@@ -220,6 +220,7 @@
 GCDEPS=
 GCOBJS=
 GCSPEC=
+JC1GCSPEC=
 GCTESTSPEC=
 case "$GC" in
  boehm)
@@ -230,6 +231,7 @@
     GCLIBS="$GCDEPS -L\$(here)/../boehm-gc/$libsubdir"
     GCINCS='-I$(top_srcdir)/../boehm-gc -I$(top_builddir)/../boehm-gc'
     GCSPEC='-lgcjgc'
+    JC1GCSPEC='-fuse-boehm-gc'
     GCTESTSPEC="-L`pwd`/../boehm-gc/.libs -rpath `pwd`/../boehm-gc/.libs"
     dnl We also want to pick up some cpp flags required when including
     dnl boehm-config.h.  Yuck.
Index: libjava/libgcj.spec.in
===================================================================
RCS file: /cvs/java/libgcj/libjava/libgcj.spec.in,v
retrieving revision 1.9
diff -u -r1.9 libgcj.spec.in
--- libgcj.spec.in	2000/04/28 16:11:56	1.9
+++ libgcj.spec.in	2000/05/07 08:46:20
@@ -6,7 +6,7 @@
 %rename lib liborig
 *lib: -lgcj -lm @GCSPEC@ @THREADSPEC@ @ZLIBSPEC@ @SYSTEMSPEC@ %(liborig)
 
-*jc1:  @DIVIDESPEC@ @EXCEPTIONSPEC@ -fasynchronous-exceptions
+*jc1:  @DIVIDESPEC@ @EXCEPTIONSPEC@ @JC1GCSPEC@ -fasynchronous-exceptions
 
 #
 # libgcc should really be a shared library.  This is a design flaw
Index: libjava/prims.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/prims.cc,v
retrieving revision 1.29
diff -u -r1.29 prims.cc
--- prims.cc	2000/05/05 02:56:14	1.29
+++ prims.cc	2000/05/07 08:46:26
@@ -319,18 +319,17 @@
   return r;
 }
 
-// Allocate a new object of class C.  SIZE is the size of the object
+// Allocate a new object of class KLASS.  SIZE is the size of the object
 // to allocate.  You might think this is redundant, but it isn't; some
 // classes, such as String, aren't of fixed size.
 jobject
-_Jv_AllocObject (jclass c, jint size)
+_Jv_AllocObject (jclass klass, jint size)
 {
-  _Jv_InitClass (c);
+  _Jv_InitClass (klass);
 
-  jobject obj = (jobject) _Jv_AllocObj (size);
+  jobject obj = (jobject) _Jv_AllocObj (size, klass);
   if (__builtin_expect (! obj, false))
     JvThrow (no_memory);
-  *((_Jv_VTable **) obj) = c->vtable;
 
   // If this class has inherited finalize from Object, then don't
   // bother registering a finalizer.  We know that finalize() is the
@@ -339,7 +338,7 @@
   // implementation would look for Object.finalize in Object's method
   // table at startup, and then use that information to find the
   // appropriate index in the method vector.
-  if (c->vtable->method[1] != ObjectClass.vtable->method[1])
+  if (klass->vtable->method[1] != ObjectClass.vtable->method[1])
     _Jv_RegisterFinalizer (obj, _Jv_FinalizeObject);
 
 #ifdef ENABLE_JVMPI
@@ -352,7 +351,7 @@
       event.event_type = JVMPI_EVENT_OBJECT_ALLOC;
       event.env_id = NULL;
       event.u.obj_alloc.arena_id = 0;
-      event.u.obj_alloc.class_id = (jobjectID) c;
+      event.u.obj_alloc.class_id = (jobjectID) klass;
       event.u.obj_alloc.is_array = 0;
       event.u.obj_alloc.size = size;
       event.u.obj_alloc.obj_id = (jobjectID) obj;
@@ -389,9 +388,9 @@
   size += count * sizeof (jobject);
 
   // FIXME: second argument should be "current loader" //
-  jclass clas = _Jv_FindArrayClass (elementClass, 0);
+  jclass klass = _Jv_FindArrayClass (elementClass, 0);
 
-  obj = (jobjectArray) _Jv_AllocArray (size);
+  obj = (jobjectArray) _Jv_AllocArray (size, klass);
   if (__builtin_expect (! obj, false))
     JvThrow (no_memory);
   obj->length = count;
@@ -403,10 +402,6 @@
       while (--count >= 0)
 	*ptr++ = init;
     }
-  // Set the vtbl last to avoid problems if the GC happens during the
-  // window in this function between the allocation and this
-  // assignment.
-  *((_Jv_VTable **) obj) = clas->vtable;
   return obj;
 }
 
@@ -428,17 +423,14 @@
 			(SIZE_T_MAX - size) / elsize, false))
     JvThrow (no_memory);
 
-  __JArray *arr = (__JArray*) _Jv_AllocObj (size + elsize * count);
+  jclass klass = _Jv_FindArrayClass (eltype, 0);
+
+  __JArray *arr = (__JArray*) _Jv_AllocObj (size + elsize * count, klass);
   if (__builtin_expect (! arr, false))
     JvThrow (no_memory);
   arr->length = count;
   // Note that we assume we are given zeroed memory by the allocator.
 
-  jclass klass = _Jv_FindArrayClass (eltype, 0);
-  // Set the vtbl last to avoid problems if the GC happens during the
-  // window in this function between the allocation and this
-  // assignment.
-  *((_Jv_VTable **) arr) = klass->vtable;
   return arr;
 }
 
Index: libjava/include/jvm.h
===================================================================
RCS file: /cvs/java/libgcj/libjava/include/jvm.h,v
retrieving revision 1.24
diff -u -r1.24 jvm.h
--- jvm.h	2000/04/27 23:13:31	1.24
+++ jvm.h	2000/05/07 08:46:26
@@ -31,7 +31,8 @@
 struct _Jv_VTable
 {
   jclass clas;
-  void *method[1];
+  void *gc_descr;
+  void *method[];
 };
 
 union _Jv_word
@@ -94,9 +95,9 @@
 typedef void _Jv_FinalizerFunc (jobject);
 
 /* Allocate space for a new Java object.  */
-void *_Jv_AllocObj (jsize size) __attribute__((__malloc__));
+void *_Jv_AllocObj (jsize size, jclass cl) __attribute__((__malloc__));
 /* Allocate space for an array of Java objects.  */
-void *_Jv_AllocArray (jsize size) __attribute__((__malloc__));
+void *_Jv_AllocArray (jsize size, jclass cl) __attribute__((__malloc__));
 /* Allocate space that is known to be pointer-free.  */
 void *_Jv_AllocBytes (jsize size) __attribute__((__malloc__));
 /* Initialize the GC.  */
Index: libjava/java/lang/Class.h
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/Class.h,v
retrieving revision 1.20
diff -u -r1.20 Class.h
--- Class.h	2000/05/05 02:56:14	1.20
+++ Class.h	2000/05/07 08:46:26
@@ -215,8 +215,8 @@
   friend jint JvNumStaticFields (jclass);
 
   friend jobject _Jv_AllocObject (jclass, jint);
-  friend jobjectArray _Jv_NewObjectArray (jsize, jclass, jobject);
-  friend jobject _Jv_NewPrimArray (jclass, jint);
+  friend void *_Jv_AllocObj (jint, jclass);
+  friend void *_Jv_AllocArray (jint, jclass);
 
   friend jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv *, jclass, jfieldID,
 					   jboolean);
Index: libjava/java/lang/natClassLoader.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/natClassLoader.cc,v
retrieving revision 1.21
diff -u -r1.21 natClassLoader.cc
--- natClassLoader.cc	2000/03/09 09:22:36	1.21
+++ natClassLoader.cc	2000/05/07 08:46:26
@@ -572,6 +572,7 @@
       vtable->clas = array_class;
       memcpy (vtable->method, ObjectClass.vtable->method,
 	      dm_count * sizeof (void *));
+      vtable->gc_descr = ObjectClass.vtable->gc_descr;
       array_class->vtable = vtable;
       array_class->vtable_method_count = ObjectClass.vtable_method_count;
 
@@ -584,6 +585,8 @@
       array_class->interfaces = interfaces;
       array_class->interface_count = 1;
 
+      // FIXME: Shouldn't this be synchronized? _Jv_PrepareConstantTimeTables
+      // needs to be called with the mutex for array_class held.
       // Generate the interface dispatch table.
       _Jv_PrepareConstantTimeTables (array_class);
 
/*
  GCTest.java.

  Run it with no arguments to loop through all tests, or a numerical
  argument 1 thru 4 to loop on a single test.
*/
   

import java.util.*;

public class GCTest
{

  static final int LOOPS = 10;
  static final int ITERATIONS = 3;
  
  static int finalized_count = 0;
  final String str = "blah blah blah blah blah blah blah blah ...";
  byte[] bytes = str.getBytes();
  long startTime;
  
  public static void main (String[] args)
  {
    new GCTest(args);
  }
  
  GCTest(String[] args)
  {
    if (args.length > 0)
      {
        int arg = Integer.parseInt(args[0]);
	while(true)
	  {
	    start();
	    switch(arg)
	    {
	    case 1:
	      smallArrays();
	      break;
	    case 2:
	      bigArrays();
              keep = new Vector(2500);
	      break;
	    case 3:
	      objArray();
	      break;
	    case 4:
	      finalization();
	      break;
	    }
	    stop();
	  }
      }
    for (int i=0; i < ITERATIONS; i++)
      {
	start(); smallArrays(); stop();
	start(); bigArrays(); stop();
	start(); objArray(); stop();
	start(); finalization();

	System.out.print(" [" + finalized_count + "] ");
	stop();		
	finalized_count = 0;
	System.out.println("   ---");
        keep = new Vector(2500);
      }
  
  }
  
  void smallArrays()
  {
    System.out.print("smallArrays() : ");
    for (int i=0; i<LOOPS; i++)
      {
	System.out.print(".");

	byte bufs[][] = new byte[200000][];
	for (int j=0; j<bufs.length; j++)
	  {
	    bufs[j] = new byte[bytes.length];
	    System.arraycopy(bytes, 0, bufs[j], 0, bytes.length);
	  }
      }
  }


  static final int ARRAY_SIZE = 500000;
  Vector keep = new Vector(2500);
  Random rand = new Random();  
  
  void bigArrays()
  {
    System.out.print("bigArrays()   : ");
    for (int i=0; i<LOOPS; i++)
      {
        System.out.print(".");
	Byte[] buf = new Byte[ARRAY_SIZE];
	for (int j=0; j<buf.length; j++)
	{
	  buf[j] = new Byte((byte)0x012);
	}
	/* grab a few random bytes back and keep them somewhere */
	/*
	for (int j=0; j<250; j++)
	{
	  int k = (rand.nextInt() & Integer.MAX_VALUE) % (ARRAY_SIZE-1);
	  keep.addElement(buf[k]);
	}
	*/
      }
  }
  
  void objArray()
  {
    System.out.print("objArray()    : ");
    for (int i=0; i<LOOPS; i++)
      {
        System.out.print(".");
        SmallObj objs[] = new SmallObj[250000];
	for (int j=objs.length-1; j >= 0; j--)
	  {
	    objs[j] = new SmallObj();
	  }
      }
  }
  
  void finalization()
  {
    System.out.print("finalization(): ");
    for (int i=0; i<LOOPS; i++)
      {
        System.out.print(".");
        FinalizeObj objs[] = new FinalizeObj[100000];
	for (int j=objs.length-1; j >= 0; j--)
	  {
	    objs[j] = new FinalizeObj();
	  }
      }
  }
  
  void start()
    {
      startTime = System.currentTimeMillis();
    }
  
  void stop()
    {
      //Runtime.getRuntime().gc();
      long stopTime = System.currentTimeMillis();
      System.out.print(" "+ (stopTime - startTime) + "ms");
      System.out.print("  (heap: total=" + (Runtime.getRuntime().totalMemory() 
					/ 1024) + "K");
      System.out.println(" free=" + (Runtime.getRuntime().freeMemory() 
				     / 1024) + "K)");  
    }
  
}
public class SmallObj
{
  int a = 2;
  int b = 3;
  long c = 9996L;
  char[] d = {'a','b','c','d','e'};
}
public class FinalizeObj extends SmallObj
{
  public void finalize()
  {
    GCTest.finalized_count++;
  }
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]