一篇文章带你看懂 JVM基本结构内存模型

Posted java大数据修炼之道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一篇文章带你看懂 JVM基本结构内存模型相关的知识,希望对你有一定的参考价值。

JVM基本结构图

  • PC寄存器

1
2
3
1、每个线程拥有一个PC寄存器
2、在线程创建时创建
3、指向下一条指令的地址

方法区

1
2
3
4
5
6
7
1、保存装载的类信息
   - 类型的常量池
   - 字段、方法信息
   - 方法字节码
2、通常和永久区绑定在一起
```
###  Java堆

1、所有线程共享Java堆
2、分新生代、老年代
3、新生代分s0 s1区
4、Java堆和程序数据密切相关

1
2
3
> 在绝大多数情况下,对象首先分配在eden区,在一次新生代回收之后,如果对象还存活,则进入s0或者s1,每经过一次新生代回收,对象如果存活,它的年龄就会加1。当对象的年龄达到一定条件后,就会被认为是老年对象,从而进入老年代。

> GC分代收集


package com.jvm;
public class SimpleHeap {
  private int id;
  public SimpleHeap(int id){
    this.id = id;
  }
  public void show(){
    System.out.println(“My id is “+id);
  }

  public static void main(String[] args) {
    SimpleHeap s1 = new SimpleHeap(1);
    SimpleHeap s2 = new SimpleHeap(2);
    s1.show();
    s2.show();
  }
}

1
2
3
![Markdown](http://i2.bvimg.com/634857/f410cf1a4a78d225.png)

### Java栈

1、Java栈和线程执行相关
2、线程私有
3、先进后出
4、栈由一系列帧组成
5、静态方法和非静态方法 第一个局部变量的槽位不同,非静态第一个槽位是this的引用

1
2
3
4
5
6
7
8
9
10
- 局部变量表

> 局部变量表是栈帧的重要组成部分之一。它用于保存函数的参数以及局部变量,局部变量表中的变量只在当前函数调用中有效,当函数调用结束,随着函数栈帧的弹出销毁,局部变量表也会随之销毁。

> 由于局部变量表在栈帧之中,因此,如果函数的参数和局部变量很多,会使得局部变量表膨胀,从而每一次函数调用就会占用更多的栈空间,最终导致函数的嵌套调用次数减少。

- 操作数栈


- Java栈  栈上分配


1、小对象、栈上分配
2、大对象或者逃逸对象无法栈上分配
3、栈上分配,使用完毕,可以自动回收,减轻GC的压力

1
### 内存模型


1、每一个线程有一个工作内存和主内存独立
2、工作内存存放主存中的变量的值和拷贝

1
### 可见性


1、volatile关键字修饰
2、synchronize
3、final(一旦初始化完成,其他线程可见)

1
2

### 有序性

原: https://itstorage.github.io/share/JVM%E5%9F%BA%E6%9C%AC%E7%BB%93%E6%9E%84%E3%80%81%E5%86%85%E5%AD%98%E6%A8%A1%E5%9D%97.html

1、一个线程内会有指令重排
2、synchronize修饰了函数,可以保证指一个线程内令重排后,其他线程读取到的值是最新的

1
2

### 指令重排


1、程序顺序规则:首先保存程序顺序的前提下会出现指令重排
a=4;b= a+1; 这种情况不会指令重排
一个线程内保证语义的串行性
2、volatile规则:volatile变量的写,先发生于读
3、锁规则:解锁必然先发生在随后的加锁(lock)

往期精彩文章









·end·

—写文不易,你的转发就是对我最大的支持—


以上是关于一篇文章带你看懂 JVM基本结构内存模型的主要内容,如果未能解决你的问题,请参考以下文章

一篇文章让你全部看懂!内存-java模型-jvm结构

小白都能看懂的JVM知识,一文带你学会JVM内存模型!

一文带你看懂PaddleHub

一张图让你看懂JVM之垃圾回收算法详解

一篇文章带你看懂Cloudflare信息泄露事件

精辟:一篇文章带你看懂数据储存!