缓存伪共享问题以及解决方案缓存行填充

缓存伪共享

共享对象存在同一个缓存中,由于MESI协议,一个对象中一些不需要改变的属性因为其他改变的属性,导致整个对象的缓存进入到M被修改状态。

MESI缓存一致性协议:https://blog.csdn.net/huangyueranbbc/article/details/84554271

目前的CPU是按照64K的缓存行(Cache Line)进行读取,如果读取的数据在同一个CacheLine,就存在缓存伪共享的问题。

对象被放入一个CacheLine中,根据MSEI协议,其中一个属性改变,其他所有没有改变的属性也变得不可共享。

填充Cache Line缓存块

通过填充对象,将对象中常被改变的属性和不常改变的属性分开到不通缓存Cache Line中。避免缓存的伪共享。

未填充对象:

 public class DataPadding{
        int value;
        long modifyTime;
        boolean flag;
        long createTime;
        char key;
    }

对象结构:

# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# 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]

com.hyr.jol.demo.JOLSample_02_Alignment$DataPadding object internals:
 OFFSET  SIZE                                      TYPE DESCRIPTION                               VALUE
      0    12                                           (object header)                           N/A
     12     4                                       int DataPadding.value                         N/A
     16     8                                      long DataPadding.modifyTime                    N/A
     24     8                                      long DataPadding.createTime                    N/A
     32     2                                      char DataPadding.key                           N/A
     34     1                                   boolean DataPadding.flag                          N/A
     35     1                                           (alignment/padding gap)                  
     36     4   com.hyr.jol.demo.JOLSample_02_Alignment DataPadding.this$0                        N/A
Instance size: 40 bytes
Space losses: 1 bytes internal + 0 bytes external = 1 bytes total

填充后对象:

public class DataPadding{
    long a1,a2,a3,a4,a5,a6,a7,a8;//防止与前一个对象产生伪共享
    int value;
    long modifyTime;
    long b1,b2,b3,b4,b5,b6,b7,b8;//防止不相关变量伪共享;
    boolean flag;
    long c1,c2,c3,c4,c5,c6,c7,c8;//
    long createTime;
    char key;
    long d1,d2,d3,d4,d5,d6,d7,d8;//防止与下一个对象产生伪共享
}

对象结构:

# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# 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]

com.hyr.jol.demo.JOLSample_02_Alignment$DataPadding object internals:
 OFFSET  SIZE                                      TYPE DESCRIPTION                               VALUE
      0    12                                           (object header)                           N/A
     12     4                                       int DataPadding.value                         N/A
     16     8                                      long DataPadding.a1                            N/A
     24     8                                      long DataPadding.a2                            N/A
     32     8                                      long DataPadding.a3                            N/A
     40     8                                      long DataPadding.a4                            N/A
     48     8                                      long DataPadding.a5                            N/A
     56     8                                      long DataPadding.a6                            N/A
     64     8                                      long DataPadding.a7                            N/A
     72     8                                      long DataPadding.a8                            N/A
     80     8                                      long DataPadding.modifyTime                    N/A
     88     8                                      long DataPadding.b1                            N/A
     96     8                                      long DataPadding.b2                            N/A
    104     8                                      long DataPadding.b3                            N/A
    112     8                                      long DataPadding.b4                            N/A
    120     8                                      long DataPadding.b5                            N/A
    128     8                                      long DataPadding.b6                            N/A
    136     8                                      long DataPadding.b7                            N/A
    144     8                                      long DataPadding.b8                            N/A
    152     8                                      long DataPadding.c1                            N/A
    160     8                                      long DataPadding.c2                            N/A
    168     8                                      long DataPadding.c3                            N/A
    176     8                                      long DataPadding.c4                            N/A
    184     8                                      long DataPadding.c5                            N/A
    192     8                                      long DataPadding.c6                            N/A
    200     8                                      long DataPadding.c7                            N/A
    208     8                                      long DataPadding.c8                            N/A
    216     8                                      long DataPadding.createTime                    N/A
    224     8                                      long DataPadding.d1                            N/A
    232     8                                      long DataPadding.d2                            N/A
    240     8                                      long DataPadding.d3                            N/A
    248     8                                      long DataPadding.d4                            N/A
    256     8                                      long DataPadding.d5                            N/A
    264     8                                      long DataPadding.d6                            N/A
    272     8                                      long DataPadding.d7                            N/A
    280     8                                      long DataPadding.d8                            N/A
    288     2                                      char DataPadding.key                           N/A
    290     1                                   boolean DataPadding.flag                          N/A
    291     1                                           (alignment/padding gap)                  
    292     4   com.hyr.jol.demo.JOLSample_02_Alignment DataPadding.this$0                        N/A
Instance size: 296 bytes
Space losses: 1 bytes internal + 0 bytes external = 1 bytes total

 

JDK1.8解决缓存伪共享

JDK1.8中增加了Contended注解方式来解决缓存伪共享问题。

在JDK1.8中,新增了一种注解@sun.misc.Contended,来使各个变量在Cache line中分隔开。注意,jvm需要添加参数-XX:-RestrictContended才能开启此功能 

未填充对象:

public class DataPadding{
        int value;
        long modifyTime;
        boolean flag;
        long createTime;
        char key;
    }

对象结构:

# Running 64-bit HotSpot VM.
# Using compressed oop with 0-bit shift.
# Using compressed klass with 0-bit shift.
# 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]

com.hyr.jol.demo.JOLSample_02_Alignment$DataPadding object internals:
 OFFSET  SIZE                                      TYPE DESCRIPTION                               VALUE
      0    12                                           (object header)                           N/A
     12     4                                       int DataPadding.value                         N/A
     16     8                                      long DataPadding.modifyTime                    N/A
     24     8                                      long DataPadding.createTime                    N/A
     32     2                                      char DataPadding.key                           N/A
     34     1                                   boolean DataPadding.flag                          N/A
     35     1                                           (alignment/padding gap)                  
     36     4   com.hyr.jol.demo.JOLSample_02_Alignment DataPadding.this$0                        N/A
Instance size: 40 bytes
Space losses: 1 bytes internal + 0 bytes external = 1 bytes total

使用Contended注解:

public class DataPadding {
        @sun.misc.Contended("group1")
        int value;
        @sun.misc.Contended("group1")
        long modifyTime;
        @sun.misc.Contended("group2")
        boolean flag;
        @sun.misc.Contended("group3")
        long createTime;
        @sun.misc.Contended("group3")
        char key;
}

对象结构:

# Running 64-bit HotSpot VM.
# Using compressed oop with 0-bit shift.
# Using compressed klass with 3-bit shift.
# 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]

com.hyr.jol.demo.JOLSample_02_Alignment$DataPadding object internals:
 OFFSET  SIZE                                      TYPE DESCRIPTION                               VALUE
      0    12                                           (object header)                           N/A
     12     4   com.hyr.jol.demo.JOLSample_02_Alignment DataPadding.this$0                        N/A
     16   128                                           (alignment/padding gap)                  
    144     4                                       int DataPadding.value                         N/A
    148     4                                           (alignment/padding gap)                  
    152     8                                      long DataPadding.modifyTime                    N/A
    160   128                                           (alignment/padding gap)                  
    288     1                                   boolean DataPadding.flag                          N/A
    289   135                                           (alignment/padding gap)                  
    424     8                                      long DataPadding.createTime                    N/A
    432     2                                      char DataPadding.key                           N/A
    434     6                                           (loss due to the next object alignment)
Instance size: 440 bytes
Space losses: 395 bytes internal + 6 bytes external = 401 bytes total

如果想深入了解,可以看下关于CPU Cache、Linux Cache相关的知识。

项目输出对象结构用的JOL。相关技术可以参考我的Github项目:https://github.com/huangyueranbbc/JVM_AGENT_DEMO

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值