当前位置: 首页 > article >正文

AtomicIntegerFieldUpdater能否降低内存

1. 代码如下:


import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerTest {

    final AtomicInteger startPosition = new AtomicInteger(0);
    final AtomicInteger wrotePosition = new AtomicInteger(0);
    final AtomicInteger committedPosition = new AtomicInteger(0);
    final AtomicInteger flushedPosition = new AtomicInteger(0);

    public static void main(String[] args) throws Exception {
        List<AtomicIntegerTest> list = new LinkedList<>();
        for (int i = 0; i < 1000000; i++) {
            list.add(new AtomicIntegerTest());
        }
        System.out.println("create instances 1000000");
        System.in.read();
    }
}

使用profiler 分析内存如下:
内存大小
从上图可以看出来AtomicInteger 大概占用了64M。而AtomicIntegerTest对象实例整个占用了96M.

2. 修改之后代码如下:


import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

public class AtomicIntegerFieldUpdaterTest {

    public static final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> startPosition =  AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class,"startPositionInt");
    public static final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> wrotePosition = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class,"wrotePositionInt");
    public static final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> committedPosition = AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class,"committedPositionInt");
    public static final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> flushedPosition =AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class,"flushedPositionInt");

    private volatile int startPositionInt = 0;
    private volatile int wrotePositionInt = 0;
    private volatile int committedPositionInt = 0;
    private volatile int flushedPositionInt = 0;

    public static void main(String[] args) throws Exception{
        List<AtomicIntegerFieldUpdaterTest> list = new LinkedList<>();
        for (int i = 0; i < 1000000; i++) {
            list.add(new AtomicIntegerFieldUpdaterTest());
        }
        System.out.println("create instances 1000000");
        System.in.read();
    }
}

使用profiler 分析内存如下:
在这里插入图片描述
AtomicIntegerFieldUpdaterTest整个对象大小的和为32M,相比之前的总共小了64M。大大的减少了内存的开销。

AtomicIntegerFieldUpdater如何使用

AtomicIntegerFieldUpdater必须是静态变量
被更新的变量必须被关键字volatile修饰

public class AtomicIntegerFieldUpdaterTest {
    public static final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> startPosition =  AtomicIntegerFieldUpdater.newUpdater(AtomicIntegerFieldUpdaterTest.class,"startPositionInt");

    private volatile int startPositionInt = 0;
}

4. 使用AtomicIntegerFieldUpdater后内存为什么会减少

代码如下:


import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

class FieldUpdaterTest {

    public volatile int a = 0;
    private static final AtomicIntegerFieldUpdater updater = AtomicIntegerFieldUpdater.newUpdater(FieldUpdaterTest.class, "a");
}

class AtomicTest22 {

    public volatile int a = 0;
    private AtomicInteger atomicInteger = new AtomicInteger(0);
}

public class T {
     public static void main(String[] args) {
        FieldUpdaterTest test = new FieldUpdaterTest();
        System.out.println(ClassLayout.parseInstance(test).toPrintable());

         AtomicTest22 test2 = new AtomicTest22();
        System.out.println(ClassLayout.parseInstance(test2).toPrintable());
    }
}

结果如下:

org.example.jucdemo2.atomic.FieldUpdaterTest object internals:
OFF  SZ   TYPE DESCRIPTION               VALUE
  0   8        (object header: mark)     0x0000000000000001 (non-biasable; age: 0)
  8   4        (object header: class)    0x01001200
 12   4    int FieldUpdaterTest.a        0
`Instance size: 16 bytes`
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

org.example.jucdemo2.atomic.AtomicTest22 object internals:
OFF  SZ                                        TYPE DESCRIPTION                  VALUE
  0   8                                             (object header: mark)        0x0000000000000001 (non-biasable; age: 0)
  8   4                                             (object header: class)       0x0101f0a8
 12   4                                         int AtomicTest22.a               0
 16   4   java.util.concurrent.atomic.AtomicInteger AtomicTest22.atomicInteger   (object)
 20   4                                             (object alignment gap)       
`Instance size: 24 bytes`
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

可以看到,FieldUpdaterTest比AtomicTest少了8 bytes。仔细分析上图结果,我们发现后者比前者多了4 bytes 大小的AtomicInteger对象,这也正是AtomicInteger中的成员变量int value,而AtomicIntegerFieldUpdater是staic final类型,即类变量,并不会占用当前对象的内存。正是基于AtomicIntegerFieldUpdater该使用特性,当字段所属的类会被创建大量的实例时,如果用AtomicInteger每个实例里面都要创建AtomicInteger对象,从而多出很多不必要的内存消耗。


http://www.kler.cn/a/417168.html

相关文章:

  • Day 32 卡玛笔记
  • 【Leetcode 热题 100】1143. 最长公共子序列
  • grafana面板配置opentsdb
  • Visual Studio(VS)没有显示垂直滚轮or垂直滚轮异常显示
  • Git--使用教程
  • 新能源产业的质量革命:六西格玛培训如何重塑制造竞争力
  • HTTP 探秘之旅:从入门到未来
  • 什么是 JVM?它的主要作用是什么?
  • 【海底地震仪】的发展越来越趋向于智能化、自主化、多功能化、小型化和便携化
  • vue实现弹窗输入验证码
  • 热门金融大模型整理
  • linux tcpdump编译
  • 【NOIP提高组】回文数
  • pnpm.lock.yaml,到底是干什么的?
  • 详解PyTorch中的Sequential容器:构建与优化简单卷积神经网络
  • SSE基础配置与使用
  • ARP欺骗-断网攻击
  • 基于springboot乡村养老服务管理系统源码和论文
  • 在 Mac ARM 架构(例如 M1 或 M2 芯片)上安装 Node.js
  • AI数据分析工具(二)
  • 微服务即时通讯系统的实现(服务端)----(2)
  • 简单好用的折线图绘制!
  • Profinet转Modbus TCP西门子SINAMICS G120变频器与施耐德M580通讯案例
  • C语言基础数据类型
  • 如何创建 MySQL 数据库的副本 ?
  • C#里怎么样使用new修饰符来让类智能选择基类函数还是派生类函数?