Small example of livelock regression in garbage collector for GCJ 3.3 under Win32

Øyvind Harboe oyvind.harboe@zylin.com
Tue May 20 11:39:00 GMT 2003


Ah!

Finally I got to the bottom of this. I've managed to 
put together a small example that reproduces the 
problems I've been seeing. Hopefully this testcase
is useful under Linux as well.

Short version: GCJ 3.3 will eventually livelock if an 
exception is caused in a finalize method.

Compile the program below. It will livelock under 3.3,
with 3.2 it does not livelock.




\thisiscool-gcc\gcc-3.3\bin\gcj Test.java --main=Test -o testit32.exe

public class Test
{
	public String replaceAll(String in, String a, String b)
	{
		String t = "";
		int i;
		for (i = 0; i < (in.length() - a.length() + 1); i++)
		{
			String c = in.substring(i, i + a.length());

			if (c.equals(a))
			{
				t += b;
				i = i + a.length() - 1;
			} else
			{
				t += in.substring(i, i + 1);
			}
		}
		if (i < in.length())
		{
			t += in.substring(i, in.length() - 1);
		}
		return t;
	}

	Foobar xxx;

	class Foobar
	{
		public void urk()
		{
		};

		protected void finalize() throws Throwable
		{
			/* cause an exception */
			xxx.urk();
			super.finalize();
		}

	};

	Foobar foobar;
	public void run()
	{

		for (int i = 0; i < 10; i++)
		{
			foobar = new Foobar();
			final String name = "thread #" + i + " ";
			Thread tr = new Thread(new Runnable()
			{
				public void run()
				{
					stressGB(name);
				}
			});
			tr.start();
		}

	}

	public static void main(String[] args)
	{
		new Test().run();

	}

	void stressGB(String thread)
	{
		char[] abs = { 'a', 'b', 'c', 'd' };
		String foo = "";
		for (int i = 0; i < 100000000; i++)
		{
			if ((i % 1000) == 0)
			{
				System.out.println(thread + " " + i + "
" + foo);
			}

			double r;
			r = Math.random();

			foo = foo + abs[(int) (((r * (abs.length -
1))))];
			r = Math.random();

			foo =
				replaceAll(foo, "" + abs[(int) (((r *
(abs.length - 1))))], "");
		}
	}
}



More information about the Java mailing list