[Gc] Newbie Question

Simon Gornall simon@s-a-l-t.co.uk
Mon, 10 Feb 2003 18:19:02 -0000


> > I'm trying to port across a Java program to C++, to make it run a lot
> > faster, and I thought at the same time, using an automatic
> > garbage-collection library might solve some problems...

> You might also try compiling your Java application with gcj.  Whether
> or not that helps, and how it compares to C++ code, will depend on
> the application.

Indeed - the application runs about 3 times slower under gcj - it seems
to tickle some problems with multiple threads (there are lots of threads
in the original program) on the target machine (Linux, and Irix to a lesser
extent).

> > Basically I want some of the collection classes, (Vector, Hashtable,
> > etc.) and some of the basic classes (String, Integer, etc.)
> > and not much
> > else. What is slightly confusing me is the use of explicit cleanup
> > functions.
> >
> > Assuming I implement Vector or Hashtable, I'm going to end up with
> > arrays of collectable classes, and so I'll have to 'new' them with a
> > specified cleanup function, yes ?
> Only if you need explicit cleanup.  If you just want the memory reclaimed,
no.

Ok, so if I have a constructor for JVector which does a

    JObject **_objects = new (UseGC) JObject *[numObjects];

... to a class-member variable _objects, when the JVector is deleted will
each _object have its' destructor called ? From the documentation, it
seems to not call any destructor on (_objects[N]) apart from (N== 0).

Each _object[N] will have memory allocated inside them using the (UseGC)
placement, but if their objects' destructors aren't called, I guess they
can't
free the memory allocated.

>From my trials, it seems that if I extend JString from gc_cleanup, all is
well within JString, ie:

    while (1)
        {
        JString *s = new JString("hello world");
       }

    ... doesn't run out of memory without me doing any explicit delete[] of
the wchar_t array allocated within each JString, but if I only extend from
gc, I need to do the explicit 'delete [] _str' operation. I'm guessing this
is
because the built-in cleanup code calls the destructor, which then triggers
the cleanup of memory allocated inside the object.

It's this needs-to-have-the-destructor-called behaviour that made me think
I'd need an explicit cleanup function for the array-of-objects _objects.

I guess the thing to do is to try it :-) Now the weekend is gone though,
it'll
have to wait a few days :-(

As an aside, I wrote a trivial test program:

    Java:

    int count = 0;
    while (count < 1000000)
        {
        String s = new String("hello world");
        StringBuffer sb = new StringBuffer(s);
        sb.replace(2,4,"--------");
        count ++;
        }

    C++:
    int count = 0;
    while (count < 1000000)
        {
        String *s = new String("hello world");
        StringBuffer *sb = new StringBuffer(s);
        sb->replace(2,4,"--------");
        count ++;
        }

The Java program took 970ms to do the 1M loops. The C++ program took 10
secs...
I'm assuming the reason (at the moment) is due to the C++ program using
wchar_t
rather than a fixed 2-byte 'char'. I'm going to try replacing the wchar_t
with an
'unsigned short' type and see if that makes a difference. The allocator
within the 1.4.1
JVM does seem to be quite good though - reducing the loop contents to

        char [] c = new char[32];           or char *c = new char[32];

made the Java program run in ~300ms, and the C++ program run in ~500ms with
the garbage collector library, and ~400ms with the normal non-collecting
allocator.
I'd say 100ms is well within my pain threshold as far as speed goes :-))) I
expect
the C++ to make headway over the Java program in the processing (rather than
pure memory-allocation) part of the program, so it's still well worth it to
me :-)

Thanks for your help, and for reading this far :-)

ATB,
    Simon