Posts

Showing posts from June, 2014

Adding @atomic operations to Java

Overview How might atomic operations work in Java, and is there a current alternative in OpenJDK/Hotspot it could translate to. Feedback In my previous article on  Making operations on volatile fields atomic.  it was pointed out a few times that "fixing" previous behaviour is unlikely to go ahead regardless of good intentions. An alternative to this is to add an @atomic annotation.  This has the advantage of only applying to new code and not risk breaking old code. Note: The use of a lower case name is  intentional  as it *doesn't* follow current coding conventions. Atomic operations Any field listed with an @atomic would make the whole expression atomic.  Variables which are non-volatile and non-atomic could be read at the start, or set after the completion of the expression.  The expression itself may require locking on some platforms, CAS operations or TSX depending on the CPU technology. If fields are only read, or only one is written too, this wo

Making operations on volatile fields atomic.

Overview The expected behaviour for volatile fields is that they should behave in a multi-threaded application the same as they do in a single threaded application.  They are not forbidden to behave the same way, but they are not guaranteed to behave the same way. The solution in Java 5.0+ is to use AtomicXxxx classes however these are relatively inefficient in terms of memory (they add a header and padding), performance (they add a references and little control over their relative positions), and syntactically they are not as clear to use. IMHO A simple solution if for volatile fields to act as they might be expected to do, the way JVM must support in AtomicFields which is not forbidden in the current JMM (Java- Memory Model) but not guaranteed. Why make fields volatile ? The benefit of volatile fields is that they are visible across threads and some optimisations which avoid re-reading them are disabled so you always check again the current value even if you didn't cha

Classes in the JLS 8

Overview When people refer to Java, they often include the libraries.  This could refer to just the standard libraries or third party libraries.  However, which classes are mentioned in the JLS.  It is a surprisingly short list. Types boolean, byte, short, char, int, float, long, double, void Classes Object, Class, ClassLoader, String, Thread, ThreadGroup, System, Reference, ReferenceQueue, Collection, List, Vector, Random, ArrayList, SecurityManager, Dictionary, HashSet, AbstractSet, HashMap, AbstractMap, ThreadLocal, ByteArrayInputStream, Date, Enumeration, BitSet, Observable, Collections,  Runtime, StringBuffer, MethodHandle, Arrays,  Boolean, Byte, Short, Character, Integer, Long, Float, Double, Number Interfaces List, Serializable, Cloneable, DataInput, DataOutput, Runnable, Observer, Map, Comparable, Annotation, Predicate, Iterable, Map.Entry, AutoCloseable,  Enums RetentionPolicy, ElementType. Exceptions/Errors Throwable, Exception Error, RuntimeException,

MineCraft and off heap memory

Image
Overview MineCraft is a really good example of when off heap memory can really help. The key requirement are The bulk of the retained data is a simple data structure (in minecraft's case its lots of byte[]) The usage of off heap memory can be hidden in abstraction. The test I used the following test for starting minecraft server from a seed from scratch which is a particularly expensive operation for the server. Preset the level-seed=114 in server.properties Delete the world* directories Start the server with these options to see what the GC is doing  -Xloggc:gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+PrintTenuringDistribution -Xmx6g Connect with one client Perform /worldgen village Perform /save-all Exit. To analyse the logs I am using jClarity's Censum. Standard MineCraft There is two particularly expensive things it does It caches block stage in many byte[]s It attempts to cache int[] u

Making Unsafe safer

Overview If you use Unsafe directly, you risk crashing the JVM.  This happens when you access a page of memory which hasn't been mapped and the result on Unix is a SIGSEG (if you access page 0) or SIGBUS (if you access another page which is not mapped) Using MethodHandles Wrapping Unsafe method with a MethodHandle is a possible solution.  You can add code to Method Handles to check for a zero page access. e.g. unsigned_ptr < 4096.  The reason you would add this to MethodHandle is it makes it easier to optimise away this check. Downside of this is that You have to use MethodHandles which complicates the syntax and obscures what you are really doing. It doesn't work if you don't It doesn't cover bus errors, nor could it as the mapping for the whole application is complex, and can change in any thread at any time. Optimising away the bounds check requires some work to the optimiser which is yet to be proven. Using Signals. If only there was some way t