如何创建含545460846912个元素的jshortArray?求解方案
问题解答
能否创建如此大的jshortArray?
完全不可能,核心原因有两点:
- JNI中的
jsize类型本质是32位int(绝大多数主流平台),最大值为2^31-1(约21亿),而你要创建的数组大小545460846912是这个上限的250倍以上,远超JNI的数组尺寸限制。 - Java层的数组长度同样受限于
int类型范围,new short[size]中的size必须是合法的int值,超出范围会直接抛出NegativeArraySizeException,或者像你遇到的那样因数值溢出变成非法的小值(比如320)。
另外你看到的数值从545460846912变成320,是因为64位long值转32位int时发生了溢出:取该数的低32位计算,结果正好是320。
解决方法
1. 先修正错误的帧大小值
首先要确认nGetEncoderFrameSize返回的545460846912是错误值——Speex编码器的帧大小通常是几百级别的小数值(比如160、320),这个超大值大概率是JNI层返回值类型不匹配导致的溢出:
- 检查JNI方法的签名:如果
nGetEncoderFrameSize实际返回的是小整数,确保JNI层返回类型是jint,Java层用int接收,避免用long转int导致截断。 - 修复后,帧大小会回到正常范围,此时创建
jshortArray就不会有问题。
2. 若确实需要处理超大数据(极少见)
如果真有特殊场景要处理海量音频数据,绝对不能用单个大数组,必须分块处理:
- Java层分拆数据:把大音频数据拆分成多个不超过
2^31-1个元素的short数组。 - JNI层适配分块逻辑:修改
nEncodeBuffer方法,支持分批接收数组片段,每次处理一块数据。 - 分块编码合并结果:依次调用编码方法处理每个数组块,最后合并所有编码结果。
3. 消除JNI的隐式转换警告
- 如果帧大小在int范围内:直接用
jsize(即int类型)作为NewShortArray的参数,避免用long强转,比如env->NewShortArray(合法的帧大小)。 - 如果分块处理:每个块的大小用int传入
NewShortArray,确保参数类型匹配。
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

