diff --git a/java/fury-core/src/main/java/io/fury/builder/ObjectCodecBuilder.java b/java/fury-core/src/main/java/io/fury/builder/ObjectCodecBuilder.java index 7756a5abf0..19f91e5abd 100644 --- a/java/fury-core/src/main/java/io/fury/builder/ObjectCodecBuilder.java +++ b/java/fury-core/src/main/java/io/fury/builder/ObjectCodecBuilder.java @@ -289,14 +289,25 @@ private List serializePrimitivesUnCompressed( private List serializePrimitivesCompressed( Expression bean, Expression buffer, List> primitiveGroups, int totalSize) { List expressions = new ArrayList<>(); - int numPrimitiveFields = getNumPrimitiveFields(primitiveGroups); // int/long may need extra one-byte for writing. - int growSize = (int) (totalSize + primitiveGroups.stream().mapToLong(Collection::size).sum()); + int extraSize = 0; + for (List group : primitiveGroups) { + for (Descriptor d : group) { + if (d.getRawType() == int.class) { + // varint may be written as 5bytes, use 8bytes for written as long to reduce cost. + extraSize += 4; + } else if (d.getRawType() == long.class) { + extraSize += 1; // long use 1~9 bytes. + } + } + } + int growSize = totalSize + extraSize; // After this grow, following writes can be unsafe without checks. expressions.add(new Invoke(buffer, "grow", Literal.ofInt(growSize))); // Must grow first, otherwise may get invalid address. Expression base = new Invoke(buffer, "getHeapMemory", "base", PRIMITIVE_BYTE_ARRAY_TYPE); expressions.add(base); + int numPrimitiveFields = getNumPrimitiveFields(primitiveGroups); for (List group : primitiveGroups) { ListExpression groupExpressions = new ListExpression(); Expression writerAddr =