JVM学习

Posted 奔跑的路奇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM学习相关的知识,希望对你有一定的参考价值。

JVM学习(一)

JVM 内存区域划分

1.程序计数器(线程私有)

  • 程序计数器,也被称为PC寄存器。保存的是程序当前执行的指令的地址(也可以说保存下一条指令的所在存储单元的地址)
  • 当 CPU 需要执行指令时,需要从程序计数器中得到当前需要执行的指令所在存储单元的地址,然后根据得到的地址获取到指令,在得到指令之后,程序计数器便自动加 1 或者根据转移指针得到下一条指令的地址,如此循环,直至执行完所有的指令。

为什么程序计数器是线程私有?

  • 在 JVM 中,多线程是通过线程轮流切换来获得 CPU 执行时间的,因此,在任一具体时刻,一个 CPU 的内核只会执行一条线程中的指令,因此,为了能够使得每个线程都在线程切换后能够恢复在切换之前的程序执行位置,每个线程都需要有自己独立的程序计数器。

2.Java 栈(线程私有)

  • Java 栈中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法,在栈帧中包括局部变量表、操作数栈、指向当前方法所属的类的运行时常量池的引用、方法返回地址、额外的附加信息。
局部变量表主要存放了编译期可知的各种数据类型(boolean、byte、char、short、int、float、long、double)、
对象引用(reference 类型,它不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)。
  • 当线程执行一个方法时,就会随之创建一个对应的栈帧,并将建立的栈帧压栈。
  • 当方法执行完毕之后,便会将栈帧出栈。因此可知,线程当前执行的方法所对应的栈帧必定位于 Java 栈的顶部。
    如图:

3.本地方法栈(线程私有)

  • 本地方法栈与 Java 栈的作用和原理非常相似。区别只不过是 Java 栈是为执行 Java方法服务的,而本地方法栈则是为执行本地方法(Native Method)服务的。

4.堆(线程共享)

  • Java 中的堆是用来存储对象本身的以及数组(当然,数组引用是存放在 Java 栈中的),堆是被所有线程共享的,在 JVM 中只有一个堆。
  • Java 堆是垃圾收集器管理的主要区域,因此也被称作GC 堆(Garbage Collected Heap)。从垃圾回收的角度,由于现在收集器基本都采用分代垃圾收集算法,所以 Java 堆还可以细分为:新生代和老年代;再细致一点有:Eden 空间、From Survivor、To Survivor 空间等。进一步划分的目的是更好地回收内存,或者更快地分配内存。

5.方法区(线程共享)

  • 方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。
  • 方法区还有一块内存,运行时常量池,它是每一个类或接口的常量池的运行时表示形式,在类和接口被加载到 JVM 后,对应的运行时常量池就被创建出来。

方法区和永久代的关系?

  • 方法区和永久代的关系很像 Java 中接口和类的关系,类实现了接口,而永久代就是 HotSpot 虚拟机对虚拟机规范中方法区的一种实现方式。

6.直接内存(线程共享)

  • NIO,使用 native 函数库直接分配堆外内存,不经过 JVM 内存直接访问系统物理内存的类——DirectBuffer。
  • 本机直接内存的分配不会受到 Java 堆的限制,但是,既然是内存就会受到本机总内存大小以及处理器寻址空间的限制。

最后,如果有问题,希望指正,一起进步。

以上是关于JVM学习的主要内容,如果未能解决你的问题,请参考以下文章

JVM 之类加载

Java IO学习--通道

JVM学习-jvm判断对象已死的方法

JVM学习笔记--方法调用之静态分配和动态分配

JVM基础学习之类的加载链接和初始化

绝命时刻的游戏设定