Problem with gcj/boehm-gc on windows

Boehm, Hans hans_boehm@hp.com
Sat Aug 30 00:32:00 GMT 2003


Thanks for looking into this.

I vaguely recall running into this before.  My impression was that it didn't show up
with cheap graphics cards, since the entire frame buffer is probably not mapped at once?
It may be that this has become much more common as graphics cards have gotten better. 

I'm not sure I have a machine on which I can easily look at this.  I assume the PAGE_NOCACHE
bit is not set in the AllocationProtect field either, and most data regions have type MEM_MAPPED?

Assuming none of this helps, could we make your test a bit more accurate by testing for a
region size that's either a power of 2 >= say 16MB or a multiple of 32MB?  That seems to cover all 
modern graphics cards I can think of.

Hans

> -----Original Message-----
> From: David Peroutka [mailto:djp@volny.cz]
> Sent: Sunday, August 24, 2003 10:32 AM
> To: java@gcc.gnu.org; Boehm, Hans
> Subject: Problem with gcj/boehm-gc on windows
> 
> 
> Hi,
> 
> I've tried to port my GCJ-based application from linux/ia32 
> to windows, and
> I've found a strange problem with garbage collector; it can 
> be reproduced
> using the following code:
> 
> ---- gltest.cc ----
> /* compile with `gcj gltest.cc -o gltest.exe -lopengl32 
> -lglu32 -lgdi32` */
> #include <stdio.h>
> #include <gcj/cni.h>
> #include <GL/gl.h>
> #include <GL/glu.h>
> 
> extern "C" void JvRunMain (jclass klass, int argc, const char **argv);
> 
> extern "C" {
> extern int GC_print_stats;
> extern int GC_dont_gc;
> extern int GC_no_dls;
> extern int GC_no_win32_dlls;
> }
> 
> int main(int argc, const char **argv)
> {
> 	printf("Hello\n");
> 	if (argc < 0) {
> 		gluErrorString(0); // (un)comment this to see 
> the difference
> 	}
> 
> 	GC_print_stats = 1;
> //	GC_no_win32_dlls = 0;
> //	GC_dont_precollect = 0;
> 	JvCreateJavaVM(NULL);
> 	printf("Goodbye\n");
> 	return 0;
> }
> ---- end of gltest.cc ----
> 
> On my computer, the program execution took 30 seconds.  If 
> you comment out the
> `gluErrorString` call, the execution is instant...
> 
> I've tried this code with Mohan's gcc33-20030802.zip, and 
> then with my own
> build, based on gcc-3.3.1, replacing gc with gc6.2alpha6, and 
> gc6.3alpha1,
> only to achieve the same result.
> 
> After that, I've found that the problem is caused by a very 
> large memory
> region (128MB) which is included in the static root set of the garbage
> collector.  It seems that the region corresponds to the video 
> memory on my
> graphics card (I tried that on another computer with 64MB 
> video memory, and
> the region size was, well, 64MB then).
> 
> Since I've found no clean way how to detect that the large 
> memory region
> should not be included in the root set, I've modified the 
> inclusion test with
> the following workaround:
> 
> dyn_load.c/GC_register_dynamic_libraries:
> 
>     if (buf.RegionSize < 0x2000000 /* ignore large (>32MB) regions */
>     	&& buf.State == MEM_COMMIT
>         && (protect == PAGE_EXECUTE_READWRITE
>             || protect == PAGE_READWRITE)
>         && !GC_is_heap_base(buf.AllocationBase)) {
> ...
> 
> Note that the attributes of the large region in question are:
> State == MEM_COMMIT, Type == MEM_MAPPED, Protect == PAGE_READWRITE
> 
> Any better ideas?
> 
> 
> This workaround solved the problem with the `gltest` example, 
> but not with my
> "real" application.  After successful startup the application 
> crashed with
> "Too many root sets" message.
> 
> After analysing the application's root set, I've found that 
> there is _huge_
> number (>1000) of 4096-sized memory regions included in the 
> static root set.
> 
> The application itself is designed to create real-time 
> particle effects, using
> a combination of SWT/OpenGL/CG libs, so it's rather resource 
> intensive; but
> I've no idea why it generates so many non-continuous root 
> sections.  Anyway,
> after increasing MAX_ROOT_SETS to 4096, it works.
> 
> Realizing that the huge root set is rescanned for every gcollect_inner
> (try_to_collect_inner, respectively), I've tried to exclude 
> root sections
> which do not belong to the image of my (statically linked) 
> application, but,
> apparently, with no luck.  Some simple test programs I've 
> created are working
> with slightly modifed `GC_no_win32_dlls` execution path, but the big
> application always crashed (randomly).
> 
> It'd be ideal to create a static permanent (non-temp) root 
> set, excluding any
> writeable sections from dlls.  Is it possible?
> 
> 
> Thanks a lot,
> 
> --
> David
> 



More information about the Java mailing list