Liferay 6.2-ce-ga5
Class Serializer

  extended by

public class Serializer
extends Object

Serializes data in a ClassLoader-aware manner.

The Serializer can perform better than ObjectOutputStream and DataOutputStream, with respect to encoding primary types, because it uses a more compact format (containing no BlockHeader) and simpler call stack involving BigEndianCodec, as compared to using an OutputStream wrapper on top of Bits.

For Strings, the UTF encoding for ObjectOutputStream and DataOutputStream has a 2^16=64K length limitation, which is often too restrictive. Serializer has a 2^32=4G String length limitation, which is generally more than enough. For pure ASCII character Strings, the encoding performance is almost the same, if not better, than ObjectOutputStream and DataOutputStream. For Strings containing non-ASCII characters, the Serializer encodes each char to two bytes rather than performing UTF encoding. There is a trade-off between CPU/memory performance and compression rate.

UTF encoding uses more CPU cycles to detect the unicode range for each char and the resulting output is variable length, which increases the memory burden when preparing the decoding buffer. Whereas, encoding each char to two bytes allows for better CPU/memory performance. Although inefficient with compression rates in comparison to UTF encoding, the char to two byte approach significantly simplifies the encoder's logic and the output length is predictably based on the length of the String, so the decoder can manage its decoding buffer efficiently. On average, a system uses more ASCII String scheming than non-ASCII String scheming. In most cases, when all system internal Strings are ASCII Strings and only Strings holding user input information can have non-ASCII characters, this Serializer performs best. In other cases, developers should consider using ObjectOutputStream or DataOutputStream.

For ordinary Objects, all primary type wrappers are encoded to their raw values with one byte type headers. This is much more efficient than ObjectOutputStream's serialization format for primary type wrappers. Strings are output in the same way as writeString(java.lang.String), but also with one byte type headers. Objects are serialized by a new ObjectOutputStream, so no reference handler can be used across Object serialization. This is done intentionally to isolate each object. The Serializer is highly optimized for serializing primary types, but is not as good as ObjectOutputStream for serializing complex objects.

On object serialization, the Serializer uses the ClassLoaderPool to look up the servlet context name corresponding to the object's ClassLoader. The servlet context name is written to the serialization stream. On object deserialization, the Deserializer uses the ClassLoaderPool to look up the ClassLoader corresponding to the servlet context name read from the deserialization stream. ObjectOutputStream and ObjectInputStream lack these features, making Serializer and Deserializer better choices for ClassLoader-aware Object serialization/deserialization, especially when plugins are involved.

See Also:

Nested Class Summary
protected static class Serializer.BufferNode
protected  class Serializer.BufferOutputStream
protected static class Serializer.BufferQueue
          Represents a descending byte[] queue ordered by array length.
Field Summary
protected  byte[] buffer
protected static ThreadLocal<Serializer.BufferQueue> bufferQueueThreadLocal
          Softens the local thread's pooled buffer memory.
protected  int index
protected static int THREADLOCAL_BUFFER_SIZE_MIN
Constructor Summary
Method Summary
protected  byte[] getBuffer(int ensureExtraSpace)
          Returns the required buffer length.
 ByteBuffer toByteBuffer()
 void writeBoolean(boolean b)
 void writeByte(byte b)
 void writeChar(char c)
 void writeDouble(double d)
 void writeFloat(float f)
 void writeInt(int i)
 void writeLong(long l)
 void writeObject(Serializable serializable)
 void writeShort(short s)
 void writeString(String s)
 void writeTo(OutputStream outputStream)
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Field Detail


protected static final int THREADLOCAL_BUFFER_COUNT_LIMIT


protected static final int THREADLOCAL_BUFFER_COUNT_MIN
See Also:
Constant Field Values


protected static final int THREADLOCAL_BUFFER_SIZE_LIMIT


protected static final int THREADLOCAL_BUFFER_SIZE_MIN
See Also:
Constant Field Values


protected static final ThreadLocal<Serializer.BufferQueue> bufferQueueThreadLocal
Softens the local thread's pooled buffer memory.

Technically, we should soften each pooled buffer individually to achieve the best garbage collection (GC) interaction. However, that increases complexity of pooled buffer access and also burdens the GC's SoftReference process, hurting performance.

Here, the entire ThreadLocal BufferQueue is softened. For threads that do serializing often, its BufferQueue will most likely stay valid. For threads that do serializing only occasionally, its BufferQueue will most likely be released by GC.


protected byte[] buffer


protected int index
Constructor Detail


public Serializer()
Method Detail


public ByteBuffer toByteBuffer()


public void writeBoolean(boolean b)


public void writeByte(byte b)


public void writeChar(char c)


public void writeDouble(double d)


public void writeFloat(float f)


public void writeInt(int i)


public void writeLong(long l)


public void writeObject(Serializable serializable)


public void writeShort(short s)


public void writeString(String s)


public void writeTo(OutputStream outputStream)
             throws IOException


protected final byte[] getBuffer(int ensureExtraSpace)
Returns the required buffer length. This method is final so JIT can perform an inline expansion.

ensureExtraSpace - the extra byte space required to meet the buffer's minimum length
the buffer value

Liferay 6.2-ce-ga5