OpenJDK 11中StringBuilder为何用2147483639作为安全上限?
为什么StringBuilder扩容时用2147483639作为安全边界?
在OpenJDK 11.0.19的StringBuilder源码中,2147483639这个数值是Integer.MAX_VALUE(2^31-1=2147483647)减去8的结果,选择它作为安全边界主要有两个核心原因:
避免内存分配失败与整数溢出
Java中数组长度由int类型存储,理论最大值是Integer.MAX_VALUE,但实际分配数组时,JVM需要为数组对象分配包含对象头的内存空间。以64位JVM启用压缩指针为例,数组对象头占用12字节,若直接用Integer.MAX_VALUE作为数组长度,元素总内存加对象头会超出JVM允许的单个对象最大内存限制,触发OutOfMemoryError。2147483639预留了足够空间给对象头,确保数组能被正常分配。同时也能避免扩容计算(如(oldCapacity << 1) + 2)时出现整数溢出。适配不同字符编码的存储需求
StringBuilder内部用byte[](Latin1编码,单字节存字符)或char[](UTF16编码,双字节存字符)存储内容,通过coder字段区分:- 当
coder=0(Latin1)时,SAFE_BOUND = 2147483639 >> 0 = 2147483639,对应byte数组的最大安全长度; - 当
coder=1(UTF16)时,SAFE_BOUND = 2147483639 >> 1 = 1073741819,对应char数组的最大安全长度(1073741819 * 2 = 2147483638字节,加对象头后仍在内存限制内)。
- 当
一旦扩容后的容量超过这个安全边界,源码会调用hugeCapacity方法做进一步校验:如果最小需求容量超过Integer.MAX_VALUE,直接抛出内存溢出异常;否则返回Integer.MAX_VALUE作为最终容量。
内容的提问来源于stack exchange,提问作者TdOnline
相关产品推荐
相关产品推荐

