当前位置:网站首页>慢慢学JVM之缓存行和伪共享
慢慢学JVM之缓存行和伪共享
2022-06-26 05:17:00 【青铜大神】
缓存行(Cache Line)
缓存行是CPU缓存的最小单位,CPU的缓存是由多个缓存行组成的,一个缓存行通常是64字节大小。所以一个缓存行可以存储8个long类型的变量。
CPU缓存的工作流程是每次访问缓存,如果缓存命中,会把整个缓存行读取出来进行修改。这种机制就会产生伪共享问题。
伪共享问题
伪共享问题产生在多线程环境下,线程A与线程B同时修改位于同一缓存行内的不同数据,导致缓存失效。它们会互相覆盖导致频繁的缓存未命中,
public class FalseShareTest implements Runnable {
// 并发线程数:4
public static int NUM_THREADS = 4;
// 迭代次数:100万次
public final static long ITERATIONS = 1_000_000L;
// 数组索引数
private final int arrayIndex;
// VolatileLong对象数组
private static VolatileLong[] longs;
// 花费总时长
public static long SUM_TIME = 0l;
public FalseShareTest(final int arrayIndex) {
this.arrayIndex = arrayIndex;
}
private static void runTest() throws InterruptedException {
Thread[] threads = new Thread[NUM_THREADS];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new FalseShareTest(i));
}
for (Thread t : threads) {
t.start();
}
for (Thread t : threads) {
t.join();
}
}
// 对对象数组进行修改
public void run() {
long i = ITERATIONS + 1;
while (0 != --i) {
longs[arrayIndex].value = i;
}
}
public final static class VolatileLong {
// 加volatile让变量的修改对所有线程可见
public volatile long value = 0L;
}
public static void main(final String[] args) throws Exception {
// 执行10次
for (int j = 0; j < 10; j++) {
// 构建实验对象数组
longs = new VolatileLong[NUM_THREADS];
for (int i = 0; i < longs.length; i++) {
longs[i] = new VolatileLong();
}
// 开始时间戳
final long start = System.currentTimeMillis();
// 运行测试程序
runTest();
// 结束时间戳
final long end = System.currentTimeMillis();
SUM_TIME += end - start;
}
System.out.println("总耗时:" + SUM_TIME);
}
}运行结果

如何改进?
第一种办法,由于一个缓存行可以存储64个字节,也就是8个long型变量,那我就前后各安插7各long型变量,让字段value,前不着村,后不着店。这也是高性能队列Disruptoer的解决方式。
public final static class VolatileLong {
// 填充
public long p1, p2, p3, p4, p5;
// 加volatile让变量的修改对所有线程可见
public volatile long value = 0L;
// 填充
public long p6, p7, p8, p9, p10;
}这里存在一个细节,一个long型变量在32位操作系统种占用8个字节,64位操作系统种占用16个字节,也就是说我偶们只需要5个long变量就能占满64个字节
第二种办法,使用JDK8新增的@Contented,使用@Contented注解后会增加128字节的padding,需要启动时增加-XX:-RestrictContented选项才能生效。
边栏推荐
- [latex] error type summary (hold the change)
- Setting pseudo static under fastadmin Apache
- Tensorflow and deep learning day 3
- Yunqi lab recommends experience scenarios this week, free cloud learning
- [unity3d] human computer interaction input
- Procedural life
- skimage.morphology.medial_axis
- 86.(cesium篇)cesium叠加面接收阴影效果(gltf模型)
- How to rewrite a pseudo static URL created by zenpart
- Learn from small samples and run to the sea of stars
猜你喜欢

LeetCode 19. Delete the penultimate node of the linked list

The parameter field of the callback address of the payment interface is "notify_url", and an error occurs after encoding and decoding the signed special character URL (,,,,,)

Status of processes and communication between processes

6.1 - 6.2 公钥密码学简介

基于SDN的DDoS攻击缓解

Machine learning final exercises
A beginner's entry is enough: develop mobile IM from zero

百度API地图的标注不是居中显示,而是显示在左上角是怎么回事?已解决!

Codeforces Round #802 (Div. 2)(A-D)

SOFA Weekly | 开源人—于雨、本周 QA、本周 Contributor
随机推荐
Technical past: tcp/ip protocol that has changed the world (precious pictures, caution for mobile phones)
skimage.morphology.medial_axis
[quartz] read configuration from database to realize dynamic timing task
Thoughts triggered by the fact that app applications are installed on mobile phones and do not display icons
CMakeLists.txt Template
skimage. morphology. medial_ axis
Zuul 实现动态路由
How does P2P technology reduce the bandwidth of live video by 75%?
5. < tag stack and general problems > supplement: lt.946 Verify the stack sequence (the same as the push in and pop-up sequence of offer 31. stack)
Practical cases | getting started and mastering tkinter+pyinstaller
Fedora alicloud source
Serious hazard warning! Log4j execution vulnerability is exposed!
PHP之一句话木马
《财富自由之路》读书之一点体会
Zuul implements dynamic routing
递归遍历目录结构和树状展现
LeetCode 19. Delete the penultimate node of the linked list
[unity3d] rigid body component
基于SDN的DDoS攻击缓解
Computer Vision Tools Chain