緩存僞共享問題以及解決方案緩存行填充

緩存僞共享

共享對象存在同一個緩存中,因爲MESI協議,一個對象中一些不須要改變的屬性由於其餘改變的屬性,致使整個對象的緩存進入到M被修改狀態。java

MESI緩存一致性協議:https://blog.csdn.net/huangyueranbbc/article/details/84554271git

目前的CPU是一般按照32或者64字節的緩存行(Cache Line)進行讀取,若是讀取的數據在同一個CacheLine,就存在緩存僞共享的問題。github

對象被放入一個CacheLine中,根據MSEI協議,其中一個屬性改變,其餘全部沒有改變的屬性也變得不可共享。緩存

填充Cache Line緩存塊

經過填充對象,將對象中常被改變的屬性和不常改變的屬性分開到不通緩存Cache Line中。避免緩存的僞共享。ruby

未填充對象:

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註解方式來解決緩存僞共享問題。jvm

在JDK1.8中,新增了一種註解@sun.misc.Contended,來使各個變量在Cache line中分隔開。注意,jvm須要添加參數-XX:-RestrictContended才能開啓此功能 oop

未填充對象:

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相關的知識。this

項目輸出對象結構用的JOL。相關技術能夠參考個人Github項目:https://github.com/huangyueranbbc/JVM_AGENT_DEMOspa

相關文章
相關標籤/搜索