DirectByteBuffer.array()为何存在额外字节?Android内存对齐解析
问题解答:DirectByteBuffer.array()长度超出预期的原因
这其实是Android为了内存对齐而做的底层优化,你的观察完全正确!
先看你的代码场景:
if (frameRGBABuffer == null) { frameRGBABuffer = ByteBuffer.allocateDirect(cameraHeight * cameraWidth * 4) .order(ByteOrder.nativeOrder()); } Log.d("tag",frameRGBABuffer.array().length)
按1280×720的分辨率计算,1280*720*4=3686400,但实际array()返回的数组长度多了7字节,这是因为Android在分配DirectByteBuffer对应的底层数组时,会额外预留7字节空间,用来处理内存对齐的问题。
你找到的这段源码正好解释了这个逻辑:
MemoryRef(int capacity) { VMRuntime runtime = VMRuntime.getRuntime(); buffer = (byte[]) runtime.newNonMovableArray(byte.class, capacity + 7); allocatedAddress = runtime.addressOf(buffer); // Offset is set to handle the alignment: http://b/16449607 offset = (int) (((allocatedAddress + 7) & ~(long) 7) - allocatedAddress); isAccessible = true; isFreed = false; }
这里的关键细节:
- 分配数组时直接申请了
capacity + 7的长度,也就是你需要的3686400加上7,正好对应你看到的3686407 - 然后通过计算
offset,把实际使用的内存起始地址调整到8字节对齐的位置((allocatedAddress +7) & ~7会得到最近的8字节对齐地址) - DirectByteBuffer实际操作的是从
offset开始的capacity长度的内存,底层数组的额外7字节只是用来凑齐对齐空间,不会影响你的实际数据读写
另外要注意:标准Java中的DirectByteBuffer调用array()会抛出UnsupportedOperationException,但Android的实现特殊处理了这一点,允许返回对应的底层数组,这也是你能拿到这个超长数组的原因。
内容的提问来源于stack exchange,提问作者zccneil
相关产品推荐
相关产品推荐

