This is the mail archive of the java@gcc.gnu.org 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]
Other format: [Raw text]

wierd pauses: the aftermath [win32 hash-sync and incremental GC "mostly work"]



So it turns out that it was both the win32 EnterMutex() as well as GC
causing the pauses, although EnterMutex() was responsible for the vast
bulk of the annoying delay, although GC pauses were still causing
enough delay, often enough to cause irritation when running an
interactive application.

_______________________________________________________________________
Attempt #1: hash-sync

Before I figured out that the remaining small delay was due to GC, I
thought that even win32 CriticalSections cause a delay. I spent a
long, long time last night trying to get hash synch working on
win32. I still can't get the mingw linker to preserve 8-byte alignment
-- my .o's are beautifully aligned per __attribute__((alignment(8))),
but after linking, all the _Jv_fooClass'es get moved to offsets ending
in 0xC -- clearly not 64-bit aligned. Does anybody know why this is?
I'm going to post to the mingw list as soon as I can construct a small
example for them to reproduce without libgcj.

My ugly hack to solve this was to assume that no statically allocated
subclass of Object smaller than 8 bytes will ever be
synchronize()/wait()ed on. This seems to be true for libgcj + myapp,
but clearly isn't a long-term solution. I clear the third least
significant bit on the address argument to the hash-sync versions of
JvEnterMonitor/JvEnterMutex/etc at the top of the function ("WLOG").

This hack works great with GC turned off, but sadly causes SEGV's in
the garbage collector if it's turned on. So I figure I'm close, but
not quite there.


_______________________________________________________________________
Attempt #2: incremental GC

This turned out to be much easier. Per Dr. Boehm's suggestion, I just
had read() read to a malloc()'ed (not GC_malloc()'ed) buffer, and then
copy from the buffer to the byte[] argument. Works like a charm, and
the pauses are gone. I'm quite happy with this result.

Is there any way I can create a "GC critical section" in which a GC
event is guaranteed not to occur? I assume that other threads
attempting to GC during this time period would block...

This way I can start my program in nonincremental mode to get the
throughput advantages during startup, and switch to incremental once
the GUI is displayed. With a "GC critical section", I'll be able to
test if the GC is in incremental mode every time read() is called, and
be fast (no memcpy()) if it isn't. If I had a feature like this, I
could put back support for incremental mode -- the read() hack would
be fully automatic.


Thanks!

  - 


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