java字节对齐 32 64_为什么Java对象中存在内部碎片,即使每个字段都是4字节对齐的?...

介绍:

在这样做时,我偶然发现了以下内容:

x@pc:~/Util$java -jar jol-cli-0.9-full.jar internals sun.reflect.DelegatingClassLoader

# WARNING: Unable to attach Serviceability Agent. You can try again with escalated privileges. Two options: a) use -Djol.tryWithSudo=true to try with sudo; b) echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope

# Running 64-bit HotSpot VM.

# Using compressed oop with 3-bit shift.

# Using compressed klass with 3-bit shift.

# WARNING | Compressed references base/shifts are guessed by the experiment!

# WARNING | Therefore, computed addresses are just guesses, and ARE NOT RELIABLE.

# WARNING | Make sure to attach Serviceability Agent to get the reliable addresses.

# Objects are 8 bytes aligned.

# Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

# Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

Instantiated the sample instance via sun.reflect.DelegatingClassLoader(java.lang.ClassLoader)

sun.reflect.DelegatingClassLoader object internals:

OFFSET SIZE TYPE DESCRIPTION VALUE

0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)

4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)

8 4 (object header) 3b 13 00 f8 (00111011 00010011 00000000 11111000) (-134212805)

12 4 java.lang.ClassLoader ClassLoader.parent null

16 4 java.util.concurrent.ConcurrentHashMap ClassLoader.parallelLockMap null

20 4 java.util.Map ClassLoader.package2certs (object)

24 4 java.util.Vector ClassLoader.classes (object)

28 4 java.security.ProtectionDomain ClassLoader.defaultDomain (object)

32 4 java.util.Set ClassLoader.domains (object)

36 4 java.util.HashMap ClassLoader.packages (object)

40 4 java.util.Vector ClassLoader.nativeLibraries (object)

44 4 java.lang.Object ClassLoader.assertionLock (object)

48 4 java.util.Map ClassLoader.packageAssertionStatus null

52 4 java.util.Map ClassLoader.classAssertionStatus null

56 8 (alignment/padding gap)

64 1 boolean ClassLoader.defaultAssertionStatus false

65 7 (loss due to the next object alignment)

Instance size: 72 bytes

Space losses: 8 bytes internal + 7 bytes external = 15 bytes total

题:

在这种情况下困扰我的是每个字段都是4字节对齐的(参见OFFSET列),但仍然在偏移56处添加了对齐间隙(56 8(对齐/填充间隙)).我在Java 9中做了相同的测试,并且对象布局发生了一些变化,alignemnt / padding间隙仍然存在,但是甚至大12个字节.

为什么会这样?为什么它是8字节大,我看到的所有其他对象都是4字节对齐的?我自己找不到解释.

我的系统:

openjdk version "1.8.0_151"

OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-0ubuntu0.16.04.2-b12)

OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)

使用默认设置(带压缩oops的ParallelOldGC)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这里是一个 Java 的示例代码,用于接收 protobuf 消息并解码,假设消息头的长度为 4 字节、包含消息体长度和消息类型两个字段,消息体为 protobuf 格式: ```java import java.io.InputStream; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.ByteOrder; import com.google.protobuf.Message; public class MessageReceiver { // 消息头长度 private static final int HEADER_LENGTH = 4; // 接收数据 private static int receiveData(InputStream in, byte[] buffer, int length) throws Exception { int recvLen = 0; while (recvLen < length) { int ret = in.read(buffer, recvLen, length - recvLen); if (ret < 0) { throw new Exception("Socket receive error"); } recvLen += ret; } return recvLen; } // 接收并解析消息 public static boolean receiveMessage(Socket socket, Message.Builder builder) { try { InputStream in = socket.getInputStream(); // 接收消息头 byte[] header = new byte[HEADER_LENGTH]; if (receiveData(in, header, HEADER_LENGTH) != HEADER_LENGTH) { return false; } // 解析消息头 int bodyLength = ByteBuffer.wrap(header).order(ByteOrder.LITTLE_ENDIAN).getInt(); int messageType = ByteBuffer.wrap(header, 4, 4).order(ByteOrder.LITTLE_ENDIAN).getInt(); // 接收消息体 byte[] body = new byte[bodyLength]; if (receiveData(in, body, bodyLength) != bodyLength) { return false; } // 解码消息体 builder.clear(); builder.mergeFrom(body); return true; } catch (Exception e) { e.printStackTrace(); return false; } } } ``` 使用示例: ```java Socket socket = new Socket("127.0.0.1", 8080); // 接收并解析消息 MyMessage.Builder builder = MyMessage.newBuilder(); if (MessageReceiver.receiveMessage(socket, builder)) { MyMessage msg = builder.build(); // 处理消息 ... } socket.close(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值