Michael Bien's Weblog don't panic http://michael-bien.com/mbien/feed/entries/atom 2010-12-29T11:11:15+01:00 Apache Roller (incubating) http://michael-bien.com/mbien/entry/java_binding_for_the_opencl Java Binding for the OpenCL API mbien 2010-09-10T22:49:42+02:00 2010-09-11T17:37:34+02:00 <p> I am currently working on Java Binding for the <a href="http://en.wikipedia.org/wiki/Opencl">OpenCL</a> API using <a href="http://jogamp.org/gluegen/www/">GlueGen</a> (as used in <a href="http://jogl.jogamp.org">JOGL</a>, <a href="http://joal.jogamp.org">JOAL</a>). The project started as part of my bachelor of CS thesis short after the release of the first OpenCL specification draft and is now fully feature complete with OpenCL 1.1. <a href="http://jogamp.org/jocl/www/">JOCL</a> is currently in the stabilization phase, a beta release shouldn't be far away. </p> <h3>Overview - How does it work?</h3> JOCL enables applications running on the JVM to use OpenCL for massively parallel, high performance computing tasks, executed on heterogeneous hardware (GPUs, CPUs, FPGAs etc) in a platform independent manner. JOCL consists of two parts, the low level and the high level binding. <p> The <b>low level bindings (LLB)</b> are automatically generated using the official OpenCL <a href="http://www.khronos.org/registry/cl/">headers</a> as input and provide a high performance, JNI based, 1:1 mapping to the C functions. </p> <p>This has the following advantages:</p> <ul> <li>reduces maintenance overhead and ensures spec conformance</li> <li>compiletime JNI bindings are the fastest way to access native libs from the JVM</li> <li>makes translating OpenCL C code into Java + JOCL very easy (e.g. from books or tutorials)</li> <li>flexibility and stability: OpenCL libs are loaded dynamically and accessed via function pointers</li> </ul> <p> The hand written <b>high level bindings (HLB)</b> is build on top of LLB and hides most boilerplate code (like object IDs, pointers and resource management) behind easy to use java objects. HLB use direct NIO buffers internally for fast memory transfers between the JVM and the OpenCL implementation and is very GC friendly. Most of the API is designed for method chaining but of course you don't have to use it this way if you don't want to. JOCL also seamlessly integrates with JOGL 2 (both are built and tested together). Just pass the JOGL context as parameter to the JOCL context factory and you will receive a shared context. If you already know OpenCL and Java, HLB should be very intuitive for you. </p> <p> The project is available on <a href="http://jocl.jogamp.org">jogamp.org</a>. Please use the <a href="http://jogamp.org/forum.html">mailinglist / forum</a> for feedback or questions and the <a href="http://jogamp.org/bugzilla/">bugtracker</a> if you experience any issues. The JOCL <a href="http://github.com/mbien/jocl">root repository</a> is located on github, you may also want to take a look at the <a href="http://github.com/mbien/jocl-demos">jocl-demos</a> project. (If the demos are not enough you might also want to take a look at the junit tests) </p> <h3>Screenshots (sourcecode in jocl-demos project):</h3> <a href="http://jogamp.org/jocl/www/Julia3d.png"><img src="http://jogamp.org/jocl/www/Julia3d_sm.png" width="400" height="300" alt="JOCL Julia Set"></img></a> <img src="http://jogamp.org/jocl/www/mandelbrot64_sm.png" width="256" height="256" alt="high precision"></img> <p> More regarding OpenGL interoperability and other features in upcoming blog entries. </p> <p> The following sample shows basic setup, computation and cleanup using the high level APIs. </p> <h3>Hello World or parallel a+b=c</h3> <pre class="brush: java;"> /** * Hello Java OpenCL example. Adds all elements of buffer A to buffer B * and stores the result in buffer C. * Sample was inspired by the Nvidia VectorAdd example written in C/C++ * which is bundled in the Nvidia OpenCL SDK. * @author Michael Bien */ public class HelloJOCL { public static void main(String[] args) throws IOException { // Length of arrays to process (arbitrary number) int elementCount = 11444777; // Local work size dimensions int localWorkSize = 256; // rounded up to the nearest multiple of the localWorkSize int globalWorkSize = roundUp(localWorkSize, elementCount); // setup CLContext context = CLContext.create(); CLProgram program = context.createProgram( HelloJOCL.class.getResourceAsStream("VectorAdd.cl") ).build(); CLBuffer&lt;FloatBuffer&gt; clBufferA = context.createFloatBuffer(globalWorkSize, READ_ONLY); CLBuffer&lt;FloatBuffer&gt; clBufferB = context.createFloatBuffer(globalWorkSize, READ_ONLY); CLBuffer&lt;FloatBuffer&gt; clBufferC = context.createFloatBuffer(globalWorkSize, WRITE_ONLY); out.println("used device memory: " + (clBufferA.getSize()+clBufferB.getSize()+clBufferC.getSize())/1000000 +"MB"); // fill read buffers with random numbers (just to have test data). fillBuffer(clBufferA.getBuffer(), 12345); fillBuffer(clBufferB.getBuffer(), 67890); // get a reference to the kernel functon with the name 'VectorAdd' // and map the buffers to its input parameters. CLKernel kernel = program.createCLKernel("VectorAdd"); kernel.putArgs(clBufferA, clBufferB, clBufferC).putArg(elementCount); // create command queue on fastest device. CLCommandQueue queue = context.getMaxFlopsDevice().createCommandQueue(); // asynchronous write to GPU device, // blocking read later to get the computed results back. long time = nanoTime(); queue.putWriteBuffer(clBufferA, false) .putWriteBuffer(clBufferB, false) .put1DRangeKernel(kernel, 0, globalWorkSize, localWorkSize) .putReadBuffer(clBufferC, true); time = nanoTime() - time; // cleanup all resources associated with this context. context.release(); // print first few elements of the resulting buffer to the console. out.println("a+b=c results snapshot: "); for(int i = 0; i < 10; i++) out.print(clBufferC.getBuffer().get() + ", "); out.println("...; " + clBufferC.getBuffer().remaining() + " more"); out.println("computation took: "+(time/1000000)+"ms"); } private static final void fillBuffer(FloatBuffer buffer, int seed) { Random rnd = new Random(seed); while(buffer.remaining() != 0) buffer.put(rnd.nextFloat()*100); buffer.rewind(); } private static final int roundUp(int groupSize, int globalSize) { int r = globalSize % groupSize; if (r == 0) { return globalSize; } else { return globalSize + groupSize - r; } } } </pre> <h3>VectorAdd.cl</h3> <pre class="brush: GLSL;"> // OpenCL Kernel Function for element by element vector addition kernel void VectorAdd(global const float* a, global const float* b, global float* c, int numElements) { // get index into global data array int iGID = get_global_id(0); // bound check (equivalent to the limit on a 'for' loop) if (iGID >= numElements) { return; } // add the vector elements c[iGID] = a[iGID] + b[iGID]; } </pre> http://michael-bien.com/mbien/entry/new_getting_started_with_jogl New Getting Started with JOGL 2 tutorials mbien 2010-09-04T00:22:38+02:00 2010-09-04T00:22:38+02:00 <p> Thanks to <a href="https://sites.google.com/site/justinscsstuff/Home">Justin Stoecker</a>, computer science graduate student at the University of Miami, JOGL gets a new set of getting started tutorials: </p> <i> <p> JOGL, or Java Bindings for OpenGL, allows Java programs to access the OpenGL API for graphics programming. The graphics code in JOGL programs will look almost identical to that found in C or C++ OpenGL programs, as the API is automatically generated from C header files. This is one of the greatest strengths of JOGL, as it is quite easy to port OpenGL programs written in C or C++ to JOGL; learning JOGL is essentially learning OpenGL[...] </p> </i> <h3>Tutorials:</h3> <ul> <li><a href="https://sites.google.com/site/justinscsstuff/jogl-tutorials">index</a></li> <li><a href="https://sites.google.com/site/justinscsstuff/jogl-tutorial-1">Tutorial 1 - Environment Setup</a></li> <li><a href="https://sites.google.com/site/justinscsstuff/jogl-tutorial-2">Tutorial 2 - Creating a Window</a></li> <li><a href="https://sites.google.com/site/justinscsstuff/jogl-tutorial-3">Tutorial 3 - Creating a Render Loop</a></li> </ul> Thanks Justin!<br/> http://michael-bien.com/mbien/entry/jogl_2_composeable_pipline JOGL 2 - Composeable Pipline mbien 2010-08-25T15:27:31+02:00 2010-08-25T15:27:31+02:00 JOGL provides a feature called 'composeable pipeline' which can be quite useful in some situations. It enables you to put additional delegating layers between your java application and the OpenGL driver. A few usecases could be: <ul> <li>performance metrics</il> <li>logging, debugging or diagnostics</il> <li>to ignore specific function calls</il> </ul> It is very easy to set up. Just put this line into your code and the DebugGL layer will throw a GLException as soon an error occurs (you want this usually when you are developing the software). <pre class="brush: java;"> public void init(GLAutoDrawable drawable) { // wrap composeable pipeline in a Debug utility, all OpenGL error codes are automatically // converted to GLExceptions as soon as they appear drawable.setGL(new DebugGL3(drawable.getGL().getGL3())); //.. } </pre> Another predefined layer is TraceGL which intercepts all OpenGL calls and prints them to an output stream. <pre class="brush: java;"> drawable.setGL(new TraceGL3(drawable.getGL().getGL3(), System.out)); </pre> see also <a href="http://michael-bien.com/mbien/entry/jogl_2_opengl_profiles_explained">GL Profiles</a> <br/> http://michael-bien.com/mbien/entry/you_have_won_the_jackpot You have won the Jackpot 3.0 mbien 2010-06-03T23:16:27+02:00 2010-06-03T23:20:16+02:00 You probably remember the project called <b>Jackpot</b> which <a href="http://nighthacks.com/roller/jag/">James Gosling</a> was initially involved with. It was basically a way to migrate client code between incompatible third party libraries by specifying refactoring rules. The project was that good integrated into NetBeans that it looked dead from the outside for a long time, since it was only used internally. NetBeans 6.9 uses Jackpot for most of the in-code hints for instance. <p> There where various ways to specify the transformation rules, e.g. via a special <a href="http://bitbucket.org/jlahoda/jackpot30/wiki/RulesLanguage">declarative language</a> or even in <a href="https://lang.dev.java.net/">Annotations</a> directly in the library-code which would cause incompatibilities (or e.g in conjunction with @Deprecated). </p> <p> Jan Lahoda recently started with the efforts to make the project usable as standalone tool again. Jackpot 3.0 is available via <a href="http://bitbucket.org/jlahoda/jackpot30/wiki/Home">bitbucket</a> for early adopters. </p> <h3>Back to the Future</h3> I used this opportunity to test jackpotc (the jackpot compiler) with <a href="http://jogamp.org">JOGL</a>. What I tired is to provide transformations which transform old JOGL 1.1.1 code into latest JOGL 2 compatible client code. So firstly thanks to Jan for fixing all the bugs we run into while testing the experimental commandline compiler. <p> The first thing I did was to transform the code to properly use OpenGL <a href="http://michael-bien.com/mbien/entry/jogl_2_opengl_profiles_explained">profiles</a>. As testcode i will use the famous Gears OpenGL demo (but those kind of automatic transformations will only pay of if you use them on large codebases). Since it was written against JOGL 1.1.1 it can only use OpenGL up to version 2.x, which means we can simply use the GL2 profile. </p> <h3>Transformation Rules</h3> <pre class="brush: java;"> 'JOGL2 API change: javax.media.opengl.GL -> javax.media.opengl.GL2': javax.media.opengl.GL=>javax.media.opengl.GL2;; 'JOGL2 API change: new javax.media.opengl.GLCapabilities(javax.media.opengl.GLProfile)': new javax.media.opengl.GLCapabilities()=> new javax.media.opengl.GLCapabilities(javax.media.opengl.GLProfile.get(javax.media.opengl.GLProfile.GL2));; 'JOGL2 API change: GL gl = drawable.getGL() -> GL2 gl = drawable.getGL().getGL2()': $d.getGL() :: $d instanceof javax.media.opengl.GLAutoDrawable=> $d.getGL().getGL2();; </pre> <p> Just by looking at the transformation rules you can easily see that it is far more powerfull as any simple text replacement could be. Jackpot uses javac and can therefore work with full qualified names, <i>instanceof</i> and more. It will also correctly fix imports for you (there is currently a open bug in this area). The quotes are used as description string which will be printed when jackpotc runs on every code occurrence which applies. </p> <h3>Invoking Jackpot</h3> <pre class="brush: bash;"> jackpotc -sourcepath $SRC -cp $LIBS -d $OUTPUT\ -Ajackpot30_extra_hints=./jogl1Tojogl2.hint $FILESET </pre> <p> <b>$LIBS</b> must contain both library versions, JOGL 1.1.1 and JOGL 2. This is not optimal but it will probably work in most situations to just use both without thinking about an particular ordering or the need to do multiple iterations. </p> <h3>Results</h3> If everything runs fine the console output should look like the sample below for each transformation which applies for the given <b>$FILESET</b>: <pre class="brush: java; wrap-lines: true"> ./test/oldgears/src/jogl111/gears/Gears.java:54: warning: JOGL2 API change: GL gl = drawable.getGL() -> GL2 gl = drawable.getGL().getGL2() GL gl = drawable.getGL(); ... </pre> The final result is a diff patch located in <b>$OUTPUT/META_INF/upgrade</b> called <b>upgrade.diff</b> containing the complete changeset for the transformation. Now the only thing you have to do is to review the changes and apply them. <pre class="brush: java"> @@ -51,7 +51,7 @@ // Use debug pipeline // drawable.setGL(new DebugGL(drawable.getGL())); - GL gl = drawable.getGL(); + GL2 gl = drawable.getGL().getGL2(); ... </pre> <p> You can find the complete demo and all ready-to-run shellscripts in the tools/jackpotc folder inside JOGL's git <a href="http://github.com/mbien/jogl">repository</a>. The classic JOGL 2 Gears demo can be found in form of an applet <a href="http://jogamp.org/jogl-demos/www/applettest-jnlp.html">here</a> (uses latest hudson builds... can be unstable). </p> <p> happy coding! </p> <br/> - - - -<br/> The JOGL repositories are open for contributions. If you would like to add some rules or fix other things... feel free to fork the repos on github and commit to them. (same rule applies for all <a href="http://jogamp.org/">JogAmp</a> Projects like JOCL, JOAL, GlueGen... etc) <br/> http://michael-bien.com/mbien/entry/jogamp_at_siggraph_2010 JogAmp at SIGGRAPH 2010 mbien 2010-05-23T21:17:07+02:00 2010-05-23T21:17:07+02:00 <b>The <a href="http://jogamp.org/">JogAmp</a> team will be present at <a href="http://www.siggraph.org/s2010">SIGGRAPH</a> this year:</b> <pre> 3D & Multimedia Across Platforms and Devices Using JOGL Tuesday, 27 July | 4:00 PM - 6:00 PM This session discusses the features, contributions, and future of OpenGL, OpenCL, and OpenMax across devices and OS exposed on top of Java using the JogAmp open-source libraries. </pre> <a href="http://www.siggraph.org/s2010/for_attendees/birds_feather">link to Session</a><br/><br/> hope to meet you there.<br/><br/> <b>about <a href="http://jogamp.org/">JogAmp</a>.</b><br/> <i>JogAmp is the home of high performance Java libraries for 3D Graphics, Multimedia and Processing. JogAmp consists currently of the projects JOGL, JOCL and JOAL which provide cross platform language bindings to the OpenGL, OpenCL, OpenAL and OpenMAX APIs.</i><br/><br/> <object width="640" height="385"><param name="movie" value="http://www.youtube-nocookie.com/v/hTNfGZTnp3c&hl=en_US&fs=1&hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube-nocookie.com/v/hTNfGZTnp3c&hl=en_US&fs=1&hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object><br/> - - - -<br/> (yes i know i should start bogging again :))<br/><br/> http://michael-bien.com/mbien/entry/object_pooling_determinism_vs_throughput Object Pooling - Determinism vs. Throughput mbien 2009-08-06T00:08:40+02:00 2009-08-10T11:28:12+02:00 <p> Object pooling in java is often seen as an anti pattern and/or wasted effort - but there are still valid reasons to think about pooling for certain kind of applications.</p><p> The JVM allocates objects much faster from managed heap (young generation; contiguous and defragmented) as you could ever recycle objects from a self written pool running on top of a VM. A good configured garbage collector is also able to delete unused objects fast. GCs in fact don't delete objects explicitly, they rather evacuate all surviving objects and sweep whole memory regions in a very efficient manner and only when its necessary to reduce runtime overhead.</p><p>Object allocation (of small objects) on modern JVMs is even so fast that making a copy of immutable objects sometimes outperforms modification of mutable (and often old) objects. JVM languages like scala or clojure make heavy use of this observation. One of the reasons for that anomaly is that generational JVMs are designed to be able to deal with loads of short living objects which makes them inexpensive compared to long living objects in old generations.</p> <h3>Performance does not always mean Throughput<br /></h3> <p>Rendering a game with 60fps might be optimal throughput for a renderer but the performance might be still unacceptable when all frames are rendered in the first half of the second with the second half spent on GC ;). Even if Object Pools may not increase system throughput they can still increase determinism of your application. Here are some observations and tips which might help: <br /></p> <h3>When should I consider Object Pools?</h3> <ul> <li>GC tuning did not help - you want to try something else</li> <li>The application creates a lot of objects which die in the old generation</li> <li>Your Objects are expansive to create but easy to recycle</li> <li>Determinism, e.g response time (soft real time requirements) is more important for you than throughput</li> </ul> <h3>Pro Pooling:</h3> <ul> <li>pools reduce GC activity in peak times (worst case scenarios)</li> <li>are easy to implement and test (its basically an array ;))</li> <li>are easy to disable (inject a fake pool which returns only new Objects)</li> </ul> <h3>Con Pooling:</h3> <ul> <li>more (old) objects are referenced when a GC kicks in (increases gc overhead)</li> <li>memory leaks (don't forget to reclaim your objects!)</li> <li>cause additional problems in a multi-threaded scenario (new Object() is thread safe!)</li> <li>may decrease throughput</li> <li>cumbersome, repetitive client code</li> </ul> <p> When you decided to use pools you have to make sure to reclaim all objects as soon they are no longer used. One way of doing this is by applying the <i>static factory method</i> pattern for object allocation and a per object dispose method for deallocation. </p> <pre class="brush: java;"> /**not Thread safe!**/ public class Vector3f { private static final ObjectPool&lt;Vector3f&gt; pool; public float x, y, z; private boolean disposed; static{ pool = new &lt;Vector3f&gt;ObjectPool(1024); for(int i = 0; i < 1024; i++) { pool.reclaim(new Vector3f()); } } private Vector3f() {} public static Vector3f create(float x, float y, float z) { Vector v = pool.isEmpty() ? new Vector() : pool.get(); v.x = x; v.y = y; v.z = z; v.disposed = false; return v; } public void dispose() { if(!disposed) { disposed = true; pool.reclaim(this); } } } </pre> <p> To demonstrate the perceived performance difference I captured two flyovers of my old <a href="http://michael-bien.com/mbien/entry/pictures_of_my_old_3d">3d engine</a>. The second flyover was captured with disabled object pools. The terrain engine triangulates the ground dependent on the position and view direction of the observer which makes object allocation hard to predict. The triangulation runs in parallel to the rendering thread which made the pool implementations a bit more complex as the example above. </p> <h3>Every vertex, normal, triangle and quad-tree node is a pooled object (wireframe on mouse over)</h3> <img src="http://people.fh-landshut.de/~mbien/weblog/obj_pools/Screenshot-18_small_sol.png" name="img1" onmouseover="document.img1.src='http://people.fh-landshut.de/~mbien/weblog/obj_pools/Screenshot-19_small_wire.png'" onmouseout="document.img1.src='http://people.fh-landshut.de/~mbien/weblog/obj_pools/Screenshot-18_small_sol.png'"> </img> <h3>on the left: flyover with pre allocated object pools; right: dynamic object allocation (new Object())</h3> <video width="256" height="192" autobuffer="true" controls="true"> <source src="http://people.fh-landshut.de/~mbien/weblog/obj_pools/pooled_small.ogg" type="video/ogg"> Your browser does not support the HTML5 video tag </source> </video> <video width="256" height="192" autobuffer="true" controls="true"> <source src="http://people.fh-landshut.de/~mbien/weblog/obj_pools/dynamic_small.ogg" type="video/ogg"> Your browser does not support the HTML5 video tag </source> </source> </video> <p> Notice the pauses at 7, 17 and 26s on the flyover with disabled pools (right video). </p> <p> <i>Note on the videos: The quality is very bad since the tool I used created 700MB large files for the 30s videos a lot of frames got skipped. I even sampled them down from 1600x1200 to 1024x768 and limited the fps to 30 but the bottleneck was still the hard disk. This is the main reason why even the left video does not look smooth. (I even had to boot windows the first time in 2 years to use the tool!). I'll try to capture better vids next time.</i> </p> <h3>Conclusion</h3> <p> Using pools requires discipline, is error prone, not good for system throughput and does not play very well with threads. However there are some attempts to make them more usable in case you think you need them. The physics engine <a href="http://jbullet.advel.cz/">JBullet</a> for example uses JStackAlloc to prevent repetitive and cumbersome code by using automatic bytecode instrumentation in the build process. Type Annotations (JSR 308 targeted for <a href="http://openjdk.java.net/projects/jdk7/features/#f619">OpenJDK 7</a>) in combination with project <a href="http://projectlombok.org/">lombok</a> and/or the automatic resource management proposal might provide further possibilities for simplifying the usage of object pools in java and reduce the risk for memory leaks. </p> http://michael-bien.com/mbien/entry/using_applets_as_fallback_mode Using Applets as fallback mode for video on pre html5 browsers mbien 2009-06-23T19:04:52+02:00 2010-06-10T02:11:44+02:00 <p> The upcoming html5 standard will make it very easy to embed media of not proprietary formats in webpages. For example <a href="http://www.whatwg.org/specs/web-apps/current-work/#video">video</a> can be embedded in the same way you would probably do it with an image. But what happens when your browser does not support html5 yet? </p> <p> Firstly: don't panic! Secondly: you could consider using for example the <b>256kb</b> large <a href="http://maikmerten.livejournal.com/tag/cortado">cortado applet</a> as fallback mode, since pre html5 browsers will ignore unknown tags like the video tag they will still read the object tag. Using an applet as cross platform fallback mode for playing e.g. <a href="http://www.theora.org/">theora</a> encoded hd movies is therefore fairly easy - <b>you even don't have to convert the video to an other format</b>. </p> <p> The upcoming html5 standard will make it very easy to embed media of not proprietary formats in webpages. For example <a href="http://www.whatwg.org/specs/web-apps/current-work/#video">video</a> can be embedded in the same way you would probably do it with an image. But what happens when your browser does not support html5 yet? </p> <p> Firstly: don't panic! Secondly: you could consider using for example the <b>256kb</b> large <a href="http://maikmerten.livejournal.com/tag/cortado">cortado applet</a> as fallback mode, since pre html5 browsers will ignore unknown tags like the video tag they will still read the object tag. Using an applet as cross platform fallback mode for playing e.g. <a href="http://www.theora.org/">theora</a> encoded hd movies is therefore fairly easy - <b>you even don't have to convert the video to an other format</b>. </p> <h4>source</h4> <pre class="brush: xml;"> &lt;video width="320" height="240" controls&gt; &lt;source src="video.ogg" type="video/ogg"&gt; &lt;object width="320" height="240" type="application/x-java-applet"&gt; Your browser does not support the &lt;code&gt;video&lt;/code&gt; element and also does not support java applets. You can download the movie on http://www.bigbuckbunny.org/. &lt;param name="archive" value="my/host/cortado.jar" /&gt; &lt;param name="code" value="com.fluendo.player.Cortado.class" /&gt; &lt;param name="url" value="video.ogg" /&gt; &lt;/object&gt; &lt;/source&gt; &lt;/video&gt; </pre> <h4>400p Big Buck Bunny trailer [<a href="http://www.bigbuckbunny.org/">link</a>]</h4> <video width="640" height="480" controls> <source src="http://download.blender.org/peach/trailer/trailer_400p.ogg" type="video/ogg"> <object width="640" height="480" type="application/x-java-applet"> Your browser does not support the <code>video</code> element and also does not support java applets. You can download the movie on http://www.bigbuckbunny.org/. <param name="archive" value="http://people.fh-landshut.de/~mbien/cortado/cortado.jar" /> <param name="code" value="com.fluendo.player.Cortado.class" /> <param name="url" value="http://download.blender.org/peach/trailer/trailer_400p.ogg" /> </object> </source> </video> <p> happy coding! </p> http://michael-bien.com/mbien/entry/java_ee_6_the_salvation Java EE 6 - The Salvation mbien 2009-06-16T14:38:06+02:00 2009-06-16T15:18:04+02:00 <p><a href="http://press.adam-bien.com/"><img vspace="0" hspace="10" border="0" align="left" src="http://www.lulu.com/items/volume_65/7274000/7274143/2/preview/detail_7274143.jpg" /></a>My Brother Adam Bien released his new book <b><i>Real World Java EE Patterns - Rethinking Best Practices</i></b> yesterday. It is available as download or softcover. I am sure you will like it. (all in english)<br /></p><p>You can testread the first two chapters <a href="http://www.lulu.com/preview/paperback-book/real-world-java-ee-patterns-rethinking-best-practices/7274143">here</a>, more infos are on his <a href="http://www.adam-bien.com/roller/abien/entry/real_world_java_ee_patterns">blog</a>.</p><p>He will check in all samples of his book to this <a href="http://kenai.com/projects/javaee-patterns">projekt</a> on kenai.com - so make sure you bookmark it or do a mercurial refresh in your favourite IDE when you are interested.<br /></p> http://michael-bien.com/mbien/entry/javaone09_keynote_replays_and_technical JavaOne 09 keynote replays and technical session slides available mbien 2009-06-06T15:57:27+02:00 2009-06-09T01:22:15+02:00 <p>For those who haven't watched to the keynotes live or per live stream can now watch the <a href="http://java.sun.com/javaone/2009/general_sessions.jsp">replays</a> of all general sessions (on your favourite screen of your live - sorry couldn't resist ;)).</p><p>The good thing about that is: you can hit the fast forward button as soon as the marketing guys start talking ;).</p><p>The slides of most presentations are also <strike><a href="http://www28.cplan.com/cc230/sessions_catalog.jsp?ilc=230-1&amp;ilg=english&amp;isort=&amp;isort_type=&amp;is=yes&amp;icriteria1=+&amp;icriteria2=+&amp;icriteria8=&amp;icriteria3=&amp;icriteria9=&amp;icriteria4=+&amp;icriteria7=+">available</a></strike> [<a href="http://developers.sun.com/learning/javaoneonline/j1online.jsp?track=embedded&amp;yr=2009">updated link</a>] for download. <br /></p><p>Especially recommended are James Gosling's toy show (last session), the first two keynotes and of course the pdfs of the technical sessions.<br /></p> http://michael-bien.com/mbien/entry/enabling_the_new_java_browser Enabling the new java browser plugin on ubuntu mbien 2009-05-17T01:36:52+02:00 2009-05-17T01:39:28+02:00 <p>When you are using Ubuntu and upgraded from older releases to intrepid or jaunty you might have run into a setup bug which causes the browser to keep using the old java plugin despite having latest Java SE and plugin packages installed (e.g 1.6 update 13 from multiverse repository).</p><p>To fix this you will have to update some symlinks and let them point to the correct location.</p><p>one easy way of doing this is by using the update-alternatives command:</p><pre> sudo update-alternatives --all<br /></pre><p>this will iterate through all symlinks in /etc/alternatives which have more than one alternative and ask you which one to use. Simple update all links which point to: </p><pre>.../libjavaplugin_oji.so<br /></pre><p>to the location of the new plugin (e.g for i386):<br /> </p><pre>/usr/lib/jvm/java-6-sun/jre/lib/i386/libnpjp2.so<br /></pre><p>For all other links just hit Return. <br /></p><p>This is a little bit of a brute force approach but there shouldn't be many of them and it is the only way to make sure you don't overlook one of them since they are all called differently ;) <br /> </p><p>Next time you restart your browser the new plugin should be loaded and applets which use e.g <a href="http://michael-bien.blogdns.com/mbien/entry/java_javascript_interoperability_example">jnlp for deployment</a> (or out of process functionality) should work.<br /> </p> http://michael-bien.com/mbien/entry/java_javascript_interoperability_example Java - JavaScript Communication example mbien 2009-05-12T16:22:57+02:00 2009-07-05T16:31:45+02:00 <p>Communication between java applets and javascript code is already available <a href="http://java.sun.com/products/plugin/1.3/docs/jsobject.html">since J2SE 1.3</a> (aka <a href="http://en.wikipedia.org/wiki/LiveConnect">LiveConnect</a>, which was btw. <a href="http://www.youtube.com/watch?v=4wi9Q1x8j7E">rewritten from scratch</a> in Java 6 update 10 as part of the new plugin) and is really easy to implement. It is a simple way to break out of the sandbox and do things which would usually require full system access (a signed applet + user approval via security dialog). For example applets living in a sandbox are only allowed to read mouse events via the AWT/Swing event mechanism which works as long the mouse is over the applet. </p><p>To read e.g the mouse position globaly you would need to call <i>MouseInfo.getPointerInfo().getLocation()</i> which would cause a <i>java.security.AccessControlException: access denied.</i> However, in javascript it is trivial to track mouse events for the whole html document (e.g google adds track onclick x,y events).<br /></p><p> All you have to do is to use the object tag instead of applet tag (which is deprecated anyway) and give the object (applet) a name via the id attribute.</p><pre style="border: 1px inset ; margin: 0px; padding: 3px; overflow: auto; text-align: left;" dir="ltr" class="alt2">&lt;<font color="#ff0000"><b>form name=&quot;FishForm&quot;</b></font>&gt; <br /> &lt;object width=&quot;256&quot; height=&quot;256&quot; type=&quot;application/x-java-applet&quot; <font color="#ff0000"><b>id=&quot;CrazyFish&quot;</b></font>&gt;<br /> &lt;param value=&quot;http://people.fh-landshut.de/~mbien/weblog/java_js_interop/launch.jnlp&quot; name=&quot;jnlp_href&quot; /&gt;<br /> &lt;param value=&quot;false&quot; name=&quot;draggable&quot; /&gt;<br /> &lt;/object&gt;<br />&lt;/form&gt;<br /></pre><p>&nbsp;now you can simply call methods as usual. </p><pre style="border: 1px inset ; margin: 0px; padding: 3px; overflow: auto; text-align: left;" dir="ltr" class="alt2">&lt;script language=&quot;JavaScript1.2&quot;&gt;<br /> //...<br /> document.onmousemove = onMouseMoved;<br /><br /> var tempX = 0;<br /> var tempY = 0;<br /><br /> var applet = document<font color="#ff0000"><b>.FishForm.CrazyFish</b></font>;<br /><br /> function onMouseMoved(e) {<br /> //...<br /> // javascript -&gt; java calls<br /> applet.jsObjectOrigin(findPosX(applet), findPosY(applet));<br /> applet.jsMouseMoved(tempX, tempY)<br /> return true<br /> }<br /> //...<br /> &lt;/script&gt;<br /></pre><p>&nbsp;the other side is a plain old public method implemented in the java applet.<br /></p> <pre style="border: 1px inset ; margin: 0px; padding: 3px; overflow: auto; text-align: left;" dir="ltr" class="alt2">&nbsp; /**<br /> * called from javascript.<br /> */<br /> public void jsMouseMoved(int x, int y) {<br /> //do something usefull<br /> }</pre><p>&nbsp;RIA/Web2.0 Observer Pattern in action ;) </p> <form name="FishForm" id="FishForm"> <div id="FishBanner"> <script> var attribs = { width:256, height:256, id:'CrazyFish' }; var params = { jnlp_href:'http://people.fh-landshut.de/~mbien/weblog/java_js_interop/launch.jnlp' }; var banner0 = new Image(); banner0.src = "http://michael-bien.com/mbien/resource/banner_scripts/play.png"; var banner1 = new Image(); banner1.src = "http://michael-bien.com/mbien/resource/banner_scripts/play-active.png"; </script> <a href="javascript:deployApplet('FishForm','FishBanner',attribs,params);startEvents();" onmouseover="play.src=banner1.src;" onmouseout ="play.src=banner0.src;"> <img id='play' src="http://michael-bien.com/mbien/resource/banner_scripts/play.png" width="48" height="48" border="0" hspace="100" vspace="100"/> </a> </div> </form><p> <script language="JavaScript1.2"> <!-- function startEvents() { // Detect if the browser is IE or not. // If it is not IE, we assume that the browser is NS. var IE = document.all?true:false // If NS -- that is, !IE -- then set up for mouse capture if (!IE) document.captureEvents(Event.MOUSEMOVE) document.onmousemove = onMouseMoved; var tempX = 0; var tempY = 0; var applet = document.FishForm.CrazyFish; function onMouseMoved(e) { if (IE) { // grab the x-y pos.s if browser is IE tempX = event.clientX + document.body.scrollLeft tempY = event.clientY + document.body.scrollTop } else { // grab the x-y pos.s if browser is NS tempX = e.pageX tempY = e.pageY } // catch possible negative values in NS4 if (tempX < 0) {tempX = 0} if (tempY < 0) {tempY = 0} // javascript -> java calls applet.jsObjectOrigin(findPosX(applet), findPosY(applet)); applet.jsMouseMoved(tempX, tempY) return true } function findPosX(obj) { var curleft = 0; if (document.getElementById || document.all) { while (obj.offsetParent) { curleft += obj.offsetLeft obj = obj.offsetParent; } } else if (document.layers) curleft += obj.x; return curleft; } function findPosY(obj) { var curtop = 0; if (document.getElementById || document.all) { while (obj.offsetParent) { curtop += obj.offsetTop obj = obj.offsetParent; } } else if (document.layers) curtop += obj.y; return curtop; } } --> </script> (The applet won't work with JRE version &lt; 1.6 update 10 (or the equivalent on Mac OS) since I used the jnlp deployment mechanism, but it wouldn't have been necessary for this particular applet)</p><p>... and never forget Web 2.0 is watching you <br /></p> http://michael-bien.com/mbien/entry/fishfarm_got_second_prize_in FishFarm wins second prize in GlassFish Community Innovation Awards Program mbien 2008-10-04T17:30:23+02:00 2009-02-16T01:49:55+01:00 <img align="left" src="https://fishfarm.dev.java.net/resources/fish200.png" />I recently <a href="http://www.sun.com/aboutsun/pr/2008-09/sunflash.20080929.2.xml">won with FishFarm</a> the second prize in the GlassFish Community Innovation Awards Program -&nbsp; which is pretty cool. I would never have thought that I have a chance to win something in the GAP.<br /> <p>Since you probably don't know what FishFarm actually is, I will try to introduce it with this entry.</p> <p><b>Formal:</b></p> <blockquote> <b><a href="https://fishfarm.dev.java.net/">FishFarm</a> = Shoal + Fork/Join Framework</b> </blockquote> <blockquote> <b><a href="https://shoal.dev.java.net/">Shoal</a> = simple to use clustering framework currently based on JXTA and used within GlassFish</b> <p><b><a href="http://g.oswego.edu/dl/concurrency-interest/">Fork/Join Framework</a> = pretty cool concurrency framework for local parallelization of tasks (jsr166y targeted for Java 7)</b></p> <b>=&gt; FishFarm = simple but pretty cool solution for distributing concurrent tasks over a p2p network [q.e.d.]</b><br /> </blockquote> <p><b>Informal:</b></p> <blockquote><p> Project FishFarm is a simple solution for distributing computational intensive tasks over the network based on Java SE APIs.</p> </blockquote> <blockquote><p>The goal of this project is to take any task written in the Fork/Join Framework (JSR166y targeted for Java 7) and distribute the computation over multiple nodes in a grid. FishFarm introduces no new frameworks and is also no full featured distribution system.</p> </blockquote> <blockquote><p>The initial focus was to make the ForkJoinPool (which is a core part of jsr166y) distributable with as few code changes as possible. Thanks to Doug Lee these modifications are now in trunk of his Fork/Join Framework and he even provided a handful of utility methods to make further extensions simpler.</p> </blockquote> <p><b>How it works: </b><br /> </p> <p>All you need to make your Application distributable is to replace ForkJoinPool with FishFarm's DistributedForkJoin pool.</p> <pre> ForkJoinPool pool = new DistributedForkJoinPool();<br /><br /> // submit as many tasks you want (nothing changed)<br /> Future futureResult1 = pool.submit(new MyTask());<br /> Future futureResult2 = pool.submit(new LongRunningTask());<br /><br /> // block until done<br />&nbsp; System.out.println(&quot;result of task 1: &quot; + futureResutl1.get());<br /> // or ask if done<br /> System.out.println(&quot;task 2 isDone=&quot; + futureResutl2.isDone());<br /></pre> <p>Every DistributedForkJoinPool is member of a peer2peer network and automatically steals work from overstrained pools if idle. DistributedForkJoinPool extends ForkJoinPool and will complete submitted tasks even when working offline or on node failures. No additional configuration required.</p> <p>I wouldn't call it ready for production yet but it should be stable enough to have fun ;-)</p> <p><a href="https://fishfarm.dev.java.net/demo/">webstartable demos</a></p> <blockquote> <p><img align="baseline" src="https://fishfarm.dev.java.net/resources/aquariumTest.png" /><br /> </p> </blockquote> <p>&nbsp;-------</p> <p>In case you are wondering why you are reading this entry via the RSS feed of my brother's (<a href="http://www.adam-bien.com/roller/abien/">Adam</a>) blog. This is a bug which confuses both urls, I hope this should be fixed with the next roller deployment.</p> <p>This is <a href="http://www.michael-bien.com/roller/mbien/">Michael</a> - over and out ;-)<br /> </p> http://michael-bien.com/mbien/entry/web_3_0_alias_java Web 3.0 alias Java 6 update N + JavaFX Desktop profile anounced mbien 2008-05-07T17:59:24+02:00 2009-02-09T22:27:16+01:00 <p><p align="justify">&quot;The Workaround&quot; - better known as Web 2.0 is now no longer necessary ;).</p><p align="justify">With Java 6 update 10 and later + JavaFX Desktop profile it is possible to run REAL applications (lets call them applets) out of process in the browser. The browser sandbox is now optional, if you like the applet to persist, just drag it out of the browser and you can use it stand alone (same process -&gt; same state).</p><p align="justify">If you close it, it simple moves back to the browser, but what happens if you close the browser when the stand alone applet is still up and running you may ask? Now you technically transformed your applet to a webstart application and installed it on your system. Isn't that cool?!! Installation has never been so easy.</p><p align="justify">Additional to that a great demonstration of the Adobe - Photoshop/Illustrator exporter plugin has been shown on the JavaOne tech session where a professional designer and a java geek developed side by side a cool looking animated application without knowing concrete implementation/design details from each other*. Now you are able not just to develop techical superior applications you can also make them look awesome with minimal effort. (technically the exporter plugin exports each layer so coolest things will be possible)<br /></p><p align="justify">But this is not everything: <a href="http://java.dzone.com/articles/javafx-gets-video">missing audio and video codecs</a> are now ready to use, BDLive which brings network to your Blu-ray player has been shown and BDLive developer discs are now availabe at BDLive.com<span style="font-size: 10pt; font-family: Arial;">.</span><br /></p><p align="justify">The early access JavaFX SDK will be available in June. More information on <a href="http://javafx.com/htdocs/index.html">javafx.com</a> (well the webside does not look and feel very good but thats probably because its not written in JavaFX script... ;) )<br /> </p><p align="justify">------- </p><p align="justify">*<a href="http://java.sun.com/javaone/sf/media_shell.jsp?id=FRdamp267558">Sun Tech Session 3</a></p><p align="justify"><a href="http://news.zdnet.com/2422-13568_22-200560.html">Applets Reloaded</a> with <a href="http://blogs.sun.com/kbr/">Ken Russell</a><br /></p><p align="justify"><a href="https://jdk6.dev.java.net/plugin2/#EXPERIMENTAL_FUNCTIONALITY">Livedemo</a> including sourcecode and documentation of the draggable applet feature is now available.<br /></p></p> http://michael-bien.com/mbien/entry/netbeans_7_0_with_better NetBeans 7.0 with better desktop integration planed mbien 2008-04-01T11:42:54+02:00 2009-02-11T23:34:18+01:00 <p><p align="justify"><b><font color="#ff0000">Note:</font> </b>This entry has been posted on <b><font color="#ff0000">1. April</font> </b>2008 and <u>nothing</u> of that below is true :-)</p><div align="justify">- - - - -<br /></div><p align="justify">You probably already know a lot of changes are planed for the NetBeans 7.0 release.<br /><br />One of the bigger changes is tighter integration to the Windows Presentation Foundation for the SWT/JFace rewrite of NetBeans 7.0 similar tho the <a href="http://java.dzone.com/news/microsoft-help-improve-vista-s">Eclipse roadmap</a>. The minimum system requirement will rise to windows vista ultimate with a DirectX 10 capable graphics card and a USB stick plugged into your system (swap file for java quickstarter) to render NetBeans 7 in full HD. The primary reason for that was the out of the box Java 6 incompatibility to apple systems (who knows maybe it is compatible with MacOS X but no one will tell you because if he tried installing SE 6 on macs he/she also signed an NDA...) and the issue that many architects simple do not understand the internals of linux distributions (e.g Ubuntu) to install NetBeans.<br /></p><p align="justify"> On older cards or other operating systems JEdit will be started in compatibility mode (motif look&amp;feel and full shell support).</p> <p>The reason for that are the new consumer guidelines and download size limitations of the java 6 Update 10 release. (there is a because of backwards compatibility problems [to build 11] not fixable ArrayIndexOutOfBounds bug in the pack200 implementation - primary reason why the swing renderer does not fit into the NB 7 distribution anymore if started with Java 6 update 10).</p><p align="justify">This brings several advantages. E.g instead of playing <a href="http://download.java.net/javadesktop/plugin2/jake2/">Jake in the browser</a> (update 10 required) NetBeans 7.0 will be capable to render Halo 3 in the editor pane (with full profiler integration and 16x FSAA text overlay). Regular patches will be available via update center.<br />&nbsp;<br />Additionally to that better joystick support is planed. This should improve the navigation through larger projects and replace the &quot;go to declaration&quot; action. You may also activate the force feedback option in the new &quot;user experience&quot; tab in the options dialog to detect the files which causes unit tests to fail. (Note: not available in JEdit compatibility mode but there will be a blinking icon instead)<br /></p><p align="justify">The higher costs to develop NetBeans 7.0 make a complete free distribution not feasible but it will be still free for opensource developers (but not without limitations e.g UML diagrams will be limited to only two kind of widgets &quot;hack&quot; and &quot;ship&quot; while maintaining 100% <a href="http://weblogs.java.net/blog/chet/archive/2008/01/crystal_methodo.html">SSP</a> compatibility).<br /></p></p> http://michael-bien.com/mbien/entry/garbage_first_the_new_concurrent Garbage First - It has never been so exciting to collect garbage :) mbien 2008-02-06T17:44:19+01:00 2009-02-13T08:14:15+01:00 <p><p align="justify">If you are reading this entry, you probably already know about G1 the new <a href="http://research.sun.com/jtech/pubs/04-g1-paper-ismm.pdf">Garbage First</a> concurrent collector currently in development for Java 7.</p><p align="justify"><a href="http://blogs.sun.com/jonthecollector/">Jon Masamitsu</a> made recently a great <a href="http://blogs.sun.com/jonthecollector/entry/our_collectors">overview of all GCs</a> currently integrated into JVM of Java SE 6 and announces the new G1 collector on his weblog.</p><p align="justify">I asked him in the comments some questions about G1 and a very interesting discussion starts. <a href="http://blogs.sun.com/tony/">Tony Printezis</a> an expert from the HotSpot GC Group joined the discussion and answered all the questions very detailed. </p><p align="justify">(I have aggregated the discussion here because I think it is much easier to read if the answer follows next to the question without the noise between them) </p><div align="justify"><b>me:</b> I just recently thought about stack allocation for special kind of objects. Couldn't the hotspot compiler provide enough information to determine points in code when its safe to delete certain objects? For example many methods use temporary objects. Is it really worth to put them into the young generation? <br /></p> <p></div><p align="justify"><b>Tony: </b><i>Regarding stack allocation. I believe (and I've seen data on papers that support this) that stack allocation can pay off for GCs that (a) do not compact or (b) are not generational (or both, of course).<br /><br />In the case of (a), a non-compacting GC has an inherently slower allocation mechanism (e.g., free-list look-ups) than a compacting GC (e.g., &quot;bump-the-pointer&quot;). So, stack allocation can allow some objects to be allocated and reclaimed more cheaply (and, maybe, reduce fragmentation given that you cut down on the number of objects allocated / de-allocated from the free lists).<br /><br />In the case of (b), typically objects that are stack allocated would also be short-lived (not always, but I'd guess this holds for the majority). So, effectively, you add the equivalent of a young generation to a non-generational GC.<br /><br />For generational GCs, results show that stack allocation might not pay off that much, given that compaction (I assume that most generational GCs would compact the young generation through copying) allows generational GCs to allocate and reclaim short-lived objects very cheaply. And, given that escape analysis (which is the mechanism that statically discovers which objects do not &quot;escape&quot; a thread and hence can be safely stack allocated as no other thread will access them) might only prove that a small proportion of objects allocated by the application can be safely stack allocated (so, the benefit would be quite small overall).<br /><br />(BTW, your 3D engine in Java shots on your blog look really cool!)<br /></i><br />thank you! :)<br /></p></p> <p><p align="justify">If you are reading this entry, you probably already know about G1 the new <a href="http://research.sun.com/jtech/pubs/04-g1-paper-ismm.pdf">Garbage First</a> concurrent collector currently in development for Java 7.</p><p align="justify"><a href="http://blogs.sun.com/jonthecollector/">Jon Masamitsu</a> made recently a great <a href="http://blogs.sun.com/jonthecollector/entry/our_collectors">overview of all GCs</a> currently integrated into JVM of Java SE 6 and announces the new G1 collector on his weblog.</p><p align="justify">I asked him in the comments some questions about G1 and a very interesting discussion starts. <a href="http://blogs.sun.com/tony/">Tony Printezis</a> an expert from the HotSpot GC Group joined the discussion and answered all the questions very detailed. </p><p align="justify">(I have aggregated the discussion here because I think it is much easier to read if the answer follows next to the question without the noise between them)<br />&nbsp; <br /></p><hr align="justify" width="100%" size="2" /><div align="justify"><b>me:</b> You mentioned &quot;Parallelism and concurrency in collections&quot; in the featurelist of G1, is it already clear when a collections could be run concurrently and when would a full stop accrue?</div><p align="justify"><b>Tony:</b><i> Inititally, G1 will behave similarly to CMS, i.e., stop-the-world &quot;young GCs&quot; (with every now and then some old regions also being reclaimed during such GCs) and concurrent marking (but no sweeping, as it's not needed). But, with several advantages (compaction, better predictability, faster remarks, etc.). We have many ideas on how to proceed in the future to do even more work concurrently, but nothing is certain yet. so we will not say much else on this at this time.</i></p><hr align="justify" width="100%" size="2" /><div align="justify"><b>me:</b> I just recently thought about stack allocation for special kind of objects. Couldn't the hotspot compiler provide enough information to determine points in code when its safe to delete certain objects? For example many methods use temporary objects. Is it really worth to put them into the young generation? <br /></p> <p></div><p align="justify"><b>Tony: </b><i>Regarding stack allocation. I believe (and I've seen data on papers that support this) that stack allocation can pay off for GCs that (a) do not compact or (b) are not generational (or both, of course).<br /><br />In the case of (a), a non-compacting GC has an inherently slower allocation mechanism (e.g., free-list look-ups) than a compacting GC (e.g., &quot;bump-the-pointer&quot;). So, stack allocation can allow some objects to be allocated and reclaimed more cheaply (and, maybe, reduce fragmentation given that you cut down on the number of objects allocated / de-allocated from the free lists).<br /><br />In the case of (b), typically objects that are stack allocated would also be short-lived (not always, but I'd guess this holds for the majority). So, effectively, you add the equivalent of a young generation to a non-generational GC.<br /><br />For generational GCs, results show that stack allocation might not pay off that much, given that compaction (I assume that most generational GCs would compact the young generation through copying) allows generational GCs to allocate and reclaim short-lived objects very cheaply. And, given that escape analysis (which is the mechanism that statically discovers which objects do not &quot;escape&quot; a thread and hence can be safely stack allocated as no other thread will access them) might only prove that a small proportion of objects allocated by the application can be safely stack allocated (so, the benefit would be quite small overall).<br /><br />(BTW, your 3D engine in Java shots on your blog look really cool!)<br /></i><br />[ thank you! :) ]</p><hr align="justify" width="100%" size="2" /><p align="justify"><b>Andrew:</b> Is it worthwhile to try and collect 'cheap' garbage? Or does the cost of tracking it outweigh the benefits? One thought was having a bit on each object that indicated whether it had ever been assigned to a non-stack location, coupled with a list on each stack frame for objects that had been allocated. Then, when unwinding that stack frame you could immediately GC any object that wasn't potentially referenced from elsewhere.<br />(Note: the flag would just be turned on, no attempt would be made to reference count, etc)</p><p align="justify"><b>Tony:</b> <i>In practice doing what you're proposing is not really straightforward (even though it sounds good &quot;on paper&quot;!).</i></p><div align="justify"></p> <p></div><p align="justify"><i>The main issue is that for GCs that rely on compaction (or that at least have a copying young generation, which is basically all the GCs in HotSpot), GCing specific objects is just not possible (or at least, it's not very efficient). Compacting GCs assume that, when a GC happens, all live objects will move somewhere (to another space in copying GCs, or to the bottom of the compacting space in sliding compacting GCs) and all available free space will be in one place. This means that such GCs do not keep track of individual free chunks and makes it impossible to just reclaim specific objects. And there are several good reasons why we like such collectors, aaone of the most important ones being that they allow for very fast, very scalable bump-the-pointer allocation.</i></p><div align="justify"></p> <p></div><p align="justify"><i>Even if we could GC specific objects, how are we going to find all the objects allocated by a particular stack frame? Are we going to link them at allocation? That's extra overhead.</i></p><div align="justify"></p> <p></div><p align="justify"><i>Performance-wise, copying young generations (like the ones we have in HotSpot) are super efficient in reclaiming young, short-lived objects (they just evacuate the few survivors they come across and never even touch the dead objects; this is why they are so fast). So, in most cases, they should be able to reclaim space at least as efficiently as what you propose. In fact, they might be even more efficient, given that they don't have to iterate over the dead objects: they copy the survivors, the rest are reclaimed, done. Whereas, according to what you propose, we would have to iterate over the dead objects and de-allocate them one-by-one.<br /><br />To summarize, your scheme might work for a non-generational, non-compacting GC (where you can de-allocate specific objects). But, I can't see it working for our GCs.<br /><br />I got slightly carried away in my reply here... Hope it helps!</i></p><hr align="justify" width="100%" size="2" /><p align="justify"><b>Aaron:</b> Will the new GC also collect the non-heap (i.e. Code Cache and Perm Gen)? Or will you get rid of those two?</p><p align="justify"><b>Tony: </b><i>Right now the G1 heap replaces the young / old generations. I.e., we still have a permanent space + code cache. In the future, we might be able to incorporate the permanent space into G1 heap (there are many tricky issues that we need to resolve first to do that...). However, I don't think we'll also incorporate the code cache too.</i></p><hr align="justify" width="100%" size="2" /><p align="justify"><b>Adam:</b> How large is a region likely to be?</p><p align="justify"><b>Tony: </b><i>Right now, regions are 1MB. We allocate a contiguous block of regions for objects that are &quot;humongous&quot;, i.e. that are too large to fit in one region.</i></p><hr align="justify" width="100%" size="2" /><p align="justify"><b>Adam:</b> Will TLAB's be (partially) replaced by regions, so threads may be allocating into different regions?</p><p align="justify"><b>Tony: </b><i>No, regions will not replace TLABs. There's one allocating region and threads will allocate TLABs from it. When that region is full, then it will be &quot;retired&quot; and another one will become the allocating region. So, a single region might hold TLABs from several threads.</i></p><hr align="justify" width="100%" size="2" /><div align="justify"><b>Adam:</b> It's not obvious to me how to choose which regions have more garbage, without first having marked them, but then how do you know which region to allocate into?</div><p align="justify"><b>Tony: </b><i>As I mentioned in an earlier post, we perform a marking phase every now and then to get up-to-date liveness information. </i></p><hr align="justify" width="100%" size="2" /><div align="justify"><b>Adam:</b> When doing a young gen collection, will you compact into a different region or the same region? I.e., does it work more like a copying collector than a mark-sweep-compact? (Or am I missing something there :)</div><p align="justify"><b>Tony: </b><i>(you're not missing anything! good question) Collections are done by copying. Basically, we pick the regions we want to GC (we refer to that set of regions as the &quot;collection set&quot;) and we evacuate the surviving objects from those regions to another set (the &quot;to-space&quot;). The assumption is that to-space will have fewer regions than the collection set and this is how we reclaim space. Given that we assume that the survival rate in the collection set will be quite low (we chose which regions to GC, remember?), copying is the most efficient way to perform such collections.</i></p><hr align="justify" width="100%" size="2" /></p> http://michael-bien.com/mbien/entry/java_3d_is_dead_again Java 3D is dead (again). Long live Java 3D! ;-) mbien 2008-02-04T19:16:34+01:00 2008-02-05T12:37:24+01:00 <p><p>It was like a deja-vu for me as I read <a href="http://forums.java.net/jive/thread.jspa?threadID=36022&amp;start=0&amp;tstart=0">this announcement</a> about the future plans of the Java 3D scenegraph API. It is already the second time the development of Java 3D has been set to 'maintenance mode' and stopped for any further improvements.</p><p><b>But this time it is not bad at all. Why?</b></p><p><i>&quot;Specifically, we are working on a new 3D scene graph, as part of the<br/> JavaFX player, that will complement the 2D Scenario scene graph. Its<br/> initial focus will be 3D effects, casual games, and simple 3D viewing<br/> applications...&quot;</i></p><p>&nbsp;&nbsp;<br /><b>OK. But what about projects like <a href="https://lg3d-wonderland.dev.java.net/">Wonderland</a> which use Java 3D and are no &quot;simple 3D viewing applications&quot;?</b></p><p>It is getting even better: Project Wonderland <a href="http://forums.java.net/jive/thread.jspa?threadID=35979&amp;tstart=0">announces</a> the complete move to the <a href="http://www.jmonkeyengine.com/">JMonkeyEngine</a>!</p><p><i>&quot;As part of our recent review of Wonderland, which resulted in the API<br />cleanup tasks that are now underway, we also took a long look at our<br />graphics subsystem. Our main goal here was to ensure we could create a<br />very rich 3D experience. We also reviewed the tool chain for creating and importing<br />content into Wonderland. After careful consideration by the Wonderland<br />team, and discussion with the Java 3D team we have decided that<br />Wonderland will be best served by moving to the JMonkeyEngine scene<br />graph API... &quot;</i><br /></p><p> Now it is getting very interesting. Wonderland was always in my opinion a far to advanced project to be limited to the visual and design constrains of Java 3D (watch the videos!). The JMonkeyEngine is a full featured 3D (game) engine already used by professional game companies (NCsoft...).<br /></p><p>&nbsp;<br /><b>Still not happy?</b></p><p>then be patient and wait for Java 3D 1.5.2 (maintenance release) which will be relicensed to a dual GPLv2 + CP ex license.<br /></p></p> http://michael-bien.com/mbien/entry/java_se_6_update_n Java SE 6 Update N Early Access build 10 available + new FAQ and release dates mbien 2008-01-16T14:47:53+01:00 2008-01-22T14:23:44+01:00 <p><p>a new ea build of Java 6 Update N is available with a lot of <a target="_blank" href="http://download.java.net/jdk6/6u10/promoted/b10/changes/jdk6uN-b10.html">bugfixes</a>, ready for testing.</p>my favorite fixes:<table border="1"><tbody><tr><td><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6641571">6641571</a></td><td>RFE </td><td>Enable new plug-in as default in 6u10 b10</td></tr><tr><td><a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6524352">6524352</a></td><br/> <td>Defect </td><br/> <td>support for high-resolution mouse wheel</td></tr></tbody></table>this was actually a really annoying one :)&nbsp;<br /><p><a target="_blank" href="https://jdk6.dev.java.net/6uNea.html">release schedule</a> (on top) + download link (bottom).<br /></p><p>New <a target="_blank" href="https://jdk6.dev.java.net/6uNfaq.html#JKernel%20">Java Kernel FAQ</a> (interesting!)</p></p> http://michael-bien.com/mbien/entry/pictures_of_my_old_3d Pictures of my old 3D Engine in Java mbien 2007-12-30T18:35:36+01:00 2009-02-11T23:35:24+01:00 <p><p><br/> Here are some screenshots of my 3D Engine (codename Metaverse) I made a few years ago (click to enlarge). It is written in Java and uses <a target="_blank" href="https://jogl.dev.java.net/">JOGL</a> (JSR 231) as OpenGL binding and <a target="_blank" href="https://jinput.dev.java.net/">JInput</a> to access the controllers.<br /><br/> </p><p></p> <p><a target="_blank" href="http://people.fh-landshut.de/%7Embien/weblog/engine/surface.png"><img hspace="0" border="0" align="bottom" vspace="0" src="http://people.fh-landshut.de/%7Embien/weblog/engine/surface_small.png" /></a><a target="_blank" href="http://people.fh-landshut.de/%7Embien/weblog/engine/planet.png"><img hspace="0" border="0" align="bottom" vspace="0" src="http://people.fh-landshut.de/%7Embien/weblog/engine/planet_small.png" /></a></p><p>These shots show the real time lighting and water rendering capabilities. They also show that you are the whole time on a real 3D planet (codename potato ;) ).</p><p><a target="_blank" href="http://people.fh-landshut.de/%7Embien/weblog/engine/vehicleTest1.png"><img hspace="0" border="0" align="bottom" vspace="0" src="http://people.fh-landshut.de/%7Embien/weblog/engine/vehicleTest1_small.png" /></a><a target="_blank" href="http://people.fh-landshut.de/%7Embien/weblog/engine/globe_wire.png"><img hspace="0" border="0" align="bottom" vspace="0" src="http://people.fh-landshut.de/%7Embien/weblog/engine/globe_wire_small.png" /></a></p><p>The next shows a 'test vehicle' to test model loading, animation, physics and collision detection of the Engine. You can use this vehicle to discover the planet - it makes even a lot of fun to drive through rough terrain and try to survive jumps from steep hills ;). The other screenshot shows the planet as wireframe.<br /></p><p><a target="_blank" href="http://people.fh-landshut.de/%7Embien/weblog/engine/river2.png"><img hspace="0" border="0" align="bottom" vspace="0" src="http://people.fh-landshut.de/%7Embien/weblog/engine/river2_small.png" /></a><a target="_blank" href="http://people.fh-landshut.de/%7Embien/weblog/engine/impact2.png"><img hspace="0" border="0" align="bottom" vspace="0" src="http://people.fh-landshut.de/%7Embien/weblog/engine/impact2_small.png" /></a></p><p>The last two show the continuous triangulation of the terrain mesh and the space subdivision into a quad-tree (important for fast frustum culling and physics). The viewer is configured to be located inside the river bed.</p><p>You think that Java for 3D Graphics is like a penguin in hell? If you follow some rules to prevent stop the world garbage collections (full GCs) and prevent calls through the JNI where possible you can reach with the server (hotspot compiler) JVM performance comparable to C++ code.<br /> </p><p>The rendering performance is quite good. Even fast fly overs are rendered with 60+ fps (frames per second). If the camera stays still the renderer reaches 200+ fps on my notebook (ATI X1600) .<br /></p><p>I have currently no time to continue with this project but if I think back how fun it was to work on that engine I would love to start hacking agai<span style="text-decoration: underline;"></span>n immediately ;).</p></p>