欢迎光临
我们一直在努力

JVM 核心知识点整理(二)

四、运行时数据区

基础划分总结

  • 线程共享:堆、元数据区(方法区)
  • 线程私有:程序计数器、虚拟机栈、本地方法栈
  • 会发生 OOM(Out Of Memory,直译:内存溢出 / 内存耗尽):堆、元数据区、虚拟机栈、本地方法栈
  • 会进行 GC:堆、元数据区

在这里插入图片描述
在这里插入图片描述

1. 各区域核心说明

区域核心作用关键特点
程序计数器 记录线程当前执行指令位置,CPU 切换线程后恢复执行 **
虚拟机栈 执行 Java 方法,每个方法对应一个栈帧 线程私有;先进后出;无 GC、会 OOM;引用类型存对象地址,对象存在堆中
本地方法栈 执行 native 修饰、C/C++ 实现的本地方法 线程私有;无 GC、会 OOM
存放所有 new 出来的对象实例 JVM 最大内存区;可通过 -Xms 初始堆、-Xmx 最大堆 配置;GC 最主要区域
元数据区(方法区) 存储类结构信息、静态常量、编译后代码 线程共享;JDK1.8 用元空间替代永久代;有 GC(回收废弃类信息,条件苛刻)

2、程序计数器

作用

用来记录线程执行的指令集的位置,因为线程在执行时cpu要切换执行,需要记录线程执行的位置

特点

​1、是运行时数据区中空间最小的,运行速度最快的区域

​2、每个线程都有一个自己的程序计数器,是线程私有的,程序计数器生命周期与线程生命周期相同

​3、程序计数器是运行时数据区中唯一一个不会有内存异常情况的区域

3、虚拟机栈

概述

虚拟机栈是运行单位,管理程序如何执行,调用一个方法运行结束后出栈。

虚拟机栈主要用来运行java语言写的方法

特点

​1、是线程私有的,每个线程中调用的方法都在线程中对应的虚拟机栈中执行

​2、栈中存储局部变量

​3、虚拟机栈终会存在内存溢出问题

​4、引用类型在栈中存储的是对象的地址,对象存在堆中

​5、A线程中的方法(栈帧)不能调用B线程中的方法(栈帧)

​6、先进先出

​7、栈中不存在垃圾回收

栈帧

当一个方法被调用后,被压入虚拟机栈中称为一个栈桢

内部结构:

​局部变量表(存储局部变量的区域),

​操作数栈:操作数栈就是用来计算的区域

例如:
int a=10int b=20//a和b存储到局部变量表
int c=a+b;//从局部变量表中加载a和b到操作数栈,在操作数栈中进行运算,将运算结果赋给c,把c写到局部变量表中

4、本地方法栈&本地方法

概述

本地方法(C/C++编写):(这里指在java程序中)不是java语言实现的方法

​使用native关键字修饰的方法,没有方法体

java语言属于上层语言(开发上层应用程序)没有权限与底层硬件进行交互(如读取内存数据,读取硬盘数据)

本地方法栈用来执行本地方法,当程序中调用本地方法那么就会被加载到本地方法栈中运行

本地方法栈管理本地方法的调用

特点

​1、本地方法栈是线程私有的,每个线程都有属于自己的本地方法栈

​2、本地方法栈也会出现内存溢出

​3、本地方法栈不会出现垃圾回收

5、堆

作用

堆空间是用来存储Java中创建的对象

特点

​堆空间是运行时数据区中最大的一块内存区域

​可以根据需求通过参数设置大小(-Xms:10m(堆起始大小) -Xmx:30m(堆最大内存大小))

​堆空间会出现内存溢出的情况

​堆空间是垃圾回收的重点区域

堆内存区域划分

新生区(代):

​Eden(伊甸园区)

​ Survivor(幸存者区):From(幸存者0) ,To(幸存者1)

老年区(代)

在这里插入图片描述

为什么分区(分区目的)

根据对象存活周期和大小不同放在不同区域,不同区域使用不同 GC 算法;新生代频繁回收、老年代较少回收,提升垃圾回收整体效率。

对象创建堆内存分配

在这里插入图片描述
在这里插入图片描述

  • 新对象优先分配到 Eden(伊甸园) 区(超大对象直接进入老年代)
  • 新生代 GC:Eden 存活对象移至 Survivor From(幸存者0区),清空 Eden
  • 下次 GC:Eden + From 存活对象移至 To(幸存者1)区,清空 Eden、From
  • 对象历经15 次(默认情况下15次) GC仍存活,晋升到老年代
  • 堆空间参数

    JVM调优(面试题)

    具体参考oracle的APi文档了解具体参数,进项JVM的配置

    6、元数据区(方法区)

    概述

    主要存放类信息(属性,方法,静态常量。。。。)和编译器编译后的代码

    特点

    ​是被线程共享的

    ​物理上讲堆和方法区是整体,逻辑上讲堆和方法去是分开的

    ​方法区的大小也是可以调整的,方法区的大小决定可以加载多少类

    ​方法区也可能出现内存溢出

    方法区,栈,堆的交互关系

    在这里插入图片描述

    方法区垃圾回收

    方法区是有垃圾回收的,方法区的垃圾回收主要是回收类信息。

    类信息的回收条件比较苛刻:

    ​1、该类所常见的对象不再使用,并且回收了

    ​2、该类的Class对象也不再使用了

    ​3、加载该类的类加载器也被回收了

    7、为什么要使用元空间来替换永久代?

    1、在1.7版本里面,永久代内存是有上限的,虽然我们可以通过参数来设置,但是JVM加载的class总数、大小是很难确定的。所以很容易出现OOM(Out Of Memory,直译:内存溢出 / 内存耗尽)问题。但是元空间是存储在本地内存里面,内存上限比较大,可以很好的避免这个问题。

    2、永久代的对象是通过FullGC进行垃圾收集,也就是和老年代同时实现垃圾收集。替换成元空间以后,简化了Full GC。可以在不进行暂停的情况下并发地释放类数据,同时也提升了GC的性能

    赞(0)
    未经允许不得转载:171主机测评 » JVM 核心知识点整理(二)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址