[SPARK-1201] Do not fully materialize partitions for MEMORY_*_SER

The deserialized version of a partition may occupy much more space than the serialized version. Therefore, if a partition is to be cached with `StorageLevel.MEMORY_*_SER`, we don't need to fully unroll it into an `ArrayBuffer`, but instead we can unroll it into a potentially much smaller `ByteBuffer`. This may save us from OOMs in this case.
Maybe better to avoid the foreach closure here because return within a closure is implemented as a try-catch, and it is very error prone in the future when we wrap this whole block with a try-catch that catches general Exception ... It has happened multiple times in Spark already, and those problems are really hard to find/debug. Best to just avoid it.