From: noisebrain <zi...@co...> - 2001-05-25 21:56:47
|
Quoted from a post on javalobby, possibly relevant here Java's Newest Trick -- THE UNSAFE CLASS! Posted by Osvaldo Doederlein, 25 May 2001 Everybody who cares about performance, please check NIO and the improvements in JNI. The docs fail to state how important they are!! Let's say we want to implement an efficient 3D engine, such as Java3D or an OpenGL mapping. Up to JDK1.3, there are only two alternatives. #1 Data lives in Java objects, and when native code wants its bits, it needs to either copy the data or "pin" it, both expensive operations. #2 Data lives on the native heap, and when Java wants, it needs to do native calls, which is even more expensive. With direct buffers, we can have data blocks that live in the native heap (so the native code can read/write efficiently, and the GC will not move it), but Java code can still access it efficiently. Some "magic" is required to implement this. I looked at the sources, and there's no native code in "java.nio", instead the buffer classes use a mysterious class named "sun.misc.Unsafe" which is supposed to manipulate the native buffers without JNI penalty. This class is implemented with JNI, but it's a unique, well-known spot with well-known semantics, and the implementation is internal to the Java core (one cannot change or override it) so the JIT compiler can easily replace its code by custom code which can really access the native buffers directly. (This kind of optimization is known as semantic expansion.) So I thought, "Unsafe" is still safe because the only way to use this class is through the "java.nio" APIs, and these are supposed to not have bugs, and to check app requests (mostly bounds checks, which can also be optimized out) and untrusted code will not be able to touch the Unsafe class, right? Wrong. Try the following code: String osv = "Osvaldo"; sun.misc.Unsafe.getUnsafe().putInt(osv, 16, 2); System.err.println(osv.length()); System.err.println(osv); Run it and you will get "2" and "Os" as output. I actually changed a private field of the String object (the length). Try with different offsets and values and you will get very different results (most of them fatal crashes of the JVM). Now, it seems like Sun sneaked a mechanism similar to C#'s "unsafe" code, in the name of high performance. I am in favor of this EXCEPT that only core libraries should be allowed to use it (the getUnsafe() method is perfect for an efficient security manager check). Making this legal to application code (like it is in C#) means havoc. Well, this is a beta release, maybe the security is still missing but will be enforced later. Or maybe this is handled just like any use of JNI. Do you think this feature should be allowed for trusted, but non-core code? Back to our example, the new DirectBuffer feature of NIO & JNI can be used to significantly reduce the overhead of talking to the 3D engine. Either Java3D or a direct OpenGL mapping library could use direct buffers to implement the 3D pipeline (spitting vertex arrays, textures etc. to the 3D engine). Or maybe the Java 3D-related objects can be implemented using a ByteBuffer as the underlying storage (instead of using Java arrays), so we completely eliminate copying at least in some cases. I guess other code will benefit too (sound, device control... anything that needs a high-performance data pipeline from Java code to native support). |