美文网首页IT技术篇
深入理解Java的堆内存和线程内存

深入理解Java的堆内存和线程内存

作者: 游戏原画设计 | 来源:发表于2019-01-07 10:15 被阅读0次

我们都知道Java对象都是在堆中创建的(开启逃逸分析的情况除外),比如一个线程中有一段这样的代码:

public class A{

public int xxx;

}

通过A a = new A();会在堆中创建一个对象,并引用a 指向了堆中对象的内存地址,也就是主内存中。

也就是说线程中的引用指向了主内存中的对象地址,很多Java程序员甚至以为因为持有引用,所以对这个引用的赋值或者读取都是直接根据地址操作主内存的对象,其实并不是这样的。

如果按照这个逻辑,线程中操作的对象就是主内存中对象(为了好理解,我直接认为主内存就是堆了);直接操作堆中对象, 那就是只有一个堆中对象,也不会存在多线程下不一致问题了,因为大家都是通过地址操作同一个对象,只有一个版本,就不会有不一致问题。

可事实并不是如此。线程内存和主内存是不一样的。当线程要读取a.xxx的时候,其实是通过该引用持有的内存地址去堆中读取这个对象的属性值,赋值给线程中的变量a.xxx;修改也一样,修改完了后将这个值覆盖堆中a的xxx属性的值(怎么实现稍后讲);

Java操作内存相关的指令有8个,lock(锁定),unlock(解锁),read(读取),load(载入),use(使用),assign(赋值),store(存储)

线程对象的操作主要是通过这个几个指令实现的,而不是我们想象的直接操作。

所以多线程下的时候,每个线程都去堆中读取对象的值,拷贝到自己线程变量中使用,修改完了再覆盖回去。这才会出现不一致和读到被别人修改的数据。

volatile关键字的作用之一就是每次使用前都和主内存(堆)进行上面的读取或者写回操作,保证了线程的可见性。如果按照线程对象就是直接操作堆中对象,那就根本就不需要这个关键字了,简单想象就知道线程中的对象也不是堆中的对象这个事实了,使用这个关键字就是希望线程中的对象和堆中的对象是一致的。

回答刚才留下的坑,那我们到底是怎么去堆中读取对象的内容的呢,比如上面的a.xxx, 对象的属性的开始地址相对对象开始地址是有一个偏移量的,

每个类型都有其规定的长度,只要从开始地址读取这个类型长度的地址就可以了。下面演示一种牛B的修改内存地址处值的方法。

这个偏移量的获取方法如下:

Field field = a.getClass().getDeclaredField("xxx");

long sexOffset = unsafe.objectFieldOffset(field); //sexOffset 就是这个偏移量;

unsafe 是sun.misc.Unsafe类,是不能通过new出来的。可以通过反射获取,Unsafe类是无锁机制。

public native Object getObjectVolatile(Object arg0, long arg1);

这个方法的实现类中就可以通过对象引用和偏移地址来获取其属性值。

这个类中还有很多牛B方法,很多都是通过传说的CAS算法实现的的,其实这种算法没那么复杂就是比较和替换,比较堆中的该地址处的值是否和期望值一样,一样就执 行相应的修改操作,并返回真,不一样就放弃操作,返回假。

Java。大家都知道,我们是学Java全栈的,大家就肯定以为我有全套的Java系统教程。没错,我是有Java全套系统教程,进扣裙【47】974【9726】所示,!~

“我们相信人人都可以成为一个程序员,现在开始,找个师兄,带你入门,学习的路上不再迷茫。这里是ja+va修真院,初学者转行到互联网行业的聚集地。"

相关文章

  • 深入理解Java的堆内存和线程内存

    我们都知道Java对象都是在堆中创建的(开启逃逸分析的情况除外),比如一个线程中有一段这样的代码: public ...

  • 并发编程有关知识点(五)

    Java 内存模型 java线程安全总结 深入理解java内存模型系列文章 线程状态: 一张图让你看懂JAVA线程...

  • JVM的内存模型

    Java内存区域——堆,栈,方法区等 深入理解java虚拟机(一)虚拟机内存划分 深入理解java虚拟机(十) J...

  • JVM第二天-volatile final synchroniz

    1.JAVA内存模型 简单的讲,Java 内存模型将内存分为共享内存和本地内存。共享内存又称为堆内存,指的就是线程...

  • java内存模型

    《深入理解java内存模型》-笔记 java各线程共享使用主内存,通过共享内存通信 重排序重排序.png编译器重排...

  • volatile实现原理

    一、内存模型Java内存模型分为主内存和线程工作内存两大类。主内存:多个线程共享的内存。如下图所示,方法区和堆属于...

  • JVM-内存模型

    Java并发是基于共享内存模型实现的。学习并深入地理解__Java内存模型__,有助于开发人员了解Java的线程间...

  • JVM读书笔记

    深入理解JVM(1) : Java内存区域划分 深入理解JVM(2) : Java堆中对象创建、布局、访问全过程 ...

  • 深入理解java虚拟机之jvm内存模型

    深入理解JVM—JVM内存模型 java的内存模型包括:本地方法区,java堆,Java虚拟机栈,本地方法栈,程序...

  • java基础知识

    java 内存区域、JMM、JAVA线程模型、硬件内存模型 java内存区域分为共享区域(堆、方法区常量池)、私有...

网友评论

    本文标题:深入理解Java的堆内存和线程内存

    本文链接:https://www.haomeiwen.com/subject/fjbyrqtx.html