JVM-JMM

2020-12-02  本文已影响0人  麦大大吃不胖

by shihang.mai

JMM就是java内存模型,它描述了对象的内存布局、如何访问变量、线程的共享变量访问规则、对象分配等等

1. 对象的内存布局

在hotspot中,对象需要知道自己的类型,所以对象组成中有ClassPointer(类型指针)

2. 对象大小

2.1 压缩指针

运行

java -XX:+PrintCommandLineFlags -version

得到

-XX:InitialHeapSize=134217728 
-XX:MaxHeapSize=2147483648 
-XX:+PrintCommandLineFlags 
//开启压缩 类型指针
-XX:+UseCompressedClassPointers 
//开始压缩 引用类型
-XX:+UseCompressedOops 
-XX:+UseParallelGC 
java version "1.8.0_251"
Java(TM) SE Runtime Environment (build 1.8.0_251-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.251-b08, mixed mode)

可以看到开启了压缩指针

  1. 压缩指针存在的意义
    我们由32位计算机变为64位,虽然我们能获得的内存大了(寻址空间从2^32 次方,变为2^64次方),但是同一个对象存在堆里会花费更多的空间(类型指针和对象引用都变为了8字节)。在64位下会带来性能问题

我们开启指针压缩,可以同时获得较大的内存,也能保持32位的性能

  1. 压缩指针的实现方式

首先有一个预备消息,32位CPU为什么支持最大4G?准确来说,应该是32位CPU为什么寻址容量为4G?

  1. CPU一次性读取4字节数据,即32位
  2. 4字节代表232个地址,而内存的最小IO单位是字节,其实这个232是【由8bit组成的一组的】地址数
  3. 所以实际寻址容量 = 2^32 * 8 = 2^35 = 4G

待研究,没研究清楚

2.2 对象大小举例

3. 对象头具体包括什么

markword锁

不同的锁状态包括的东西不一样,但是:

ps:当一个对象计算过identityHashCode(没重写hashcode,调用了默认的)后,不会进入偏向锁状态

4. 对象的定位

5. 对象如何分配

对象分配
  1. 先看能不能在栈上分配。这里涉及逃逸分析,当没方法逃逸时,即可栈上分配。
  2. 如果能在栈分配,那么分配。如果不能栈分配,那么看对象大不大,如果大,直接在old区分配。
  3. 如果不大,那么会进行TLAB在自己的线程在eden区特有的区域分配
  4. 然后经过GC回收,如果达到一定条件,进入old区

参考

https://blog.csdn.net/liujianyangbj/article/details/108074167#comments_15280876

https://blog.csdn.net/liujianyangbj/article/details/108049482

上一篇下一篇

猜你喜欢

热点阅读