Liferay 6.2-ce-ga5

com.liferay.portal.kernel.io
Class Serializer

java.lang.Object
  extended by com.liferay.portal.kernel.io.Serializer

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:
Deserializer

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_COUNT_LIMIT
           
protected static int THREADLOCAL_BUFFER_COUNT_MIN
           
protected static int THREADLOCAL_BUFFER_SIZE_LIMIT
           
protected static int THREADLOCAL_BUFFER_SIZE_MIN
           
 
Constructor Summary
Serializer()
           
 
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

THREADLOCAL_BUFFER_COUNT_LIMIT

protected static final int THREADLOCAL_BUFFER_COUNT_LIMIT

THREADLOCAL_BUFFER_COUNT_MIN

protected static final int THREADLOCAL_BUFFER_COUNT_MIN
See Also:
Constant Field Values

THREADLOCAL_BUFFER_SIZE_LIMIT

protected static final int THREADLOCAL_BUFFER_SIZE_LIMIT

THREADLOCAL_BUFFER_SIZE_MIN

protected static final int THREADLOCAL_BUFFER_SIZE_MIN
See Also:
Constant Field Values

bufferQueueThreadLocal

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.


buffer

protected byte[] buffer

index

protected int index
Constructor Detail

Serializer

public Serializer()
Method Detail

toByteBuffer

public ByteBuffer toByteBuffer()

writeBoolean

public void writeBoolean(boolean b)

writeByte

public void writeByte(byte b)

writeChar

public void writeChar(char c)

writeDouble

public void writeDouble(double d)

writeFloat

public void writeFloat(float f)

writeInt

public void writeInt(int i)

writeLong

public void writeLong(long l)

writeObject

public void writeObject(Serializable serializable)

writeShort

public void writeShort(short s)

writeString

public void writeString(String s)

writeTo

public void writeTo(OutputStream outputStream)
             throws IOException
Throws:
IOException

getBuffer

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

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

Liferay 6.2-ce-ga5