导航

【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/黑马旅游/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码-CSDN博客

目录

一、JVM基本介绍

二、JVM内存模型

2.0 概述

2.1 类加载子系统

2.2 运行时数据区

2.2.0 基本介绍

2.2.1 本地方法栈:由C语言实现

2.2.2 Java方法栈(虚拟机栈)

2.2.3 方法区

2.2.3.1 基本概念 

2.2.3.2 实现方式:永久代和元空间

2.2.3.3 组成元素:类常量池、运行时常量池、字符串常量池

2.2.4 堆

2.2.5 程序计数器(PC寄存器)

2.3 执行引擎


一、JVM基本介绍

我们经常说Java一个跨平台语言,因为它是运行在Java虚拟机上(JVM)的。

在Java程序的实际编译运行过程中,编译器将Java源代码编译成字节文件后,JVM将字节翻译成特定平台机器运行程序

实际上,Java是跨平台的,JVM不是跨平台的,我们在Linuxwindows系统安装对应版本的JVM后,同一个Java代码在这些JVM上运行,从而起到跨平台效果

JDK、JRE、JVM、Java的区别

JVM是Java虚拟机,JRE是Java运行环境,JDK是个Java开发工具包,Java是门编程语言。 

二、JVM内存模型

2.0 概述

JVM由三大部分组成:加载子系统、运行时数据区、执行引擎

2.1 加载子系统

加载子系统通过类加载机制加载类的class文件,如果该类第一次加载,会执行加载、验证解析。只负责class文件的加载,至于是否可运行,则由执行引擎决定。

JVM中,类加载过程是在类加载子系统完成的。

类加载过程加载 –> 链接验证 –> 准备 –> 解析) –> 初始化

类加载过程:加载、链接验证、准备、解析)、初始化这个过程是在类加载子系统完成的。

加载:生成类的Class对象

  1. 通过一个类的全限定获取定义此类的二进制字节流(即编译生成的类的class字节文件
  2. 这个字节流所代表静态存储结构转化为方法区的运行时数据结构。包括创建运行时常量池,将类常量池的部分符号引用放入运行时常量池。
  3. 内存生成一个代表这个类的java.lang.Class对象,作为方法这个类各种数据访问入口。注意类的class对象是运行时生成的,类的class字节文件编译生成的。

链接将类的二进制数据合并到JRE中。该过程分为以下3个阶段

初始化变量赋初值、执行静态语句块。

2.2 运行时数据区

2.2.0 基本介绍

运行时数据区:程序运行时,存储程序内容例如字节码、对象参数返回值等)。

运行时数据区包括本地方法栈、虚拟机栈、方法区、堆、程序计数器

在运行时数据区中,只有方法区和堆是各线程共享进程内存区域,其他运行区都是每个线程可以独立拥有的。

图示:

2.2.1 本地方法栈:由C语言实现

本地方法栈:存放本地方法调用过程中的栈帧。

本地方法栈用于管理本地方法的调用,本地方法是C语言写的编译基于本机硬件操作系统程序

注意:不是所有虚拟机都支持本地方法栈,例如Hotspot虚拟机(HotSpot是Sun/OracleJDK和OpenJDK中的默认Java虚拟机)就是将本地方法栈和虚拟机栈合二为一。栈解决程序的运行问题,即程序如何执行、如何处理数据。

栈帧:栈帧是栈的元素,由三部分组成,即局部变量表(存方法参数局部变量)、操作数栈(存方法执行过程中的中间结果,或者其他暂存数据)和帧数据区(存方法返回地址线程引用附加信息)。

2.2.2 Java方法栈(虚拟机栈)

存放Java方法调用过程中的栈帧。用于管理Java方法的调用

Java方法是我们开发时写的Java方法

2.2.3 方法区

2.2.3.1 基本概念 

方法区:可以看作是一块独立于Java堆的内存空间,方法区是各线程共享的内存区域

2.2.3.2 实现方式永久代和元空间

方法区有两种实现方式,分别是:永久代和元空间

永久代:属于JVM方法区的内存,用来存储类的元数据,如类名、方法信息、字段信息等一些静态的数据。

永久代的特点:

空间是Hotspot在JDK8引入的,用于取代永久代。

空间属于本地内存,由操作系统直接管理,不再受JVM管理。

同时内存空间可以自动扩容,避免内存溢出默认情况下元空间可以无限使用本地内存,也可以通过-XX:MetaspaceSize限制内存大小

方法区和永久代、元空间关系方法区是一个抽象概念,永久代和元空间是方法区的实现方式

2.2.3.3 组成元素:类常量池、运行时常量池、字符串常量池

常量池:就是一张表,JVM根据这张常量表找到要执行的类信息和方法信息

2.2.4 堆

堆:存放对象实例、实例变量数组,包括新生代(伊甸园区、幸存区S0和S1)和老年代

堆是垃圾收集器管理的内存区域

解决的是数据存储的问题,即数据怎么放、放在哪儿。堆实际内存空间可以不连续,大小可以选择固定大小或可扩展,堆是各线程共享的内存区域

堆的GC流程

  1.  首先,任何新对象都分配eden 空间两个幸存者空间开始时都是空的。
  2. eden 空间填满时,将触发一个Minor GC(年轻代的垃圾回收,也称为Young GC),删除所有未引用的对象,大对象需要大量连续内存空间的Java对象,如那种很长的字符串)直接进入年代
  3. 所有被引用的对象作为存活对象,将移动第一个幸存者空间S0,并标记年龄为1,即经历过一次Minor GC。之后每经过一次Minor GC,年龄+1。GC分代年龄存储在对象头的Mark Word里。
  4. eden 空间再次被填满时,会执行第二次Minor GC,将Eden和S0区中所有垃圾对象清除,并将存活对象复制到S1并年龄加1,此时S0变为空
  5. 如此反复在S0和S1之间切换几次之后,还存活的年龄等于15的对象(JDK8默认15,JDK9默认7,-XX:InitialTenuringThreshold=7)在下一次Minor GC时将放到年代中。 
  6. 当老年代满了时会触发Major GC(也称为Full GC),Major GC 清理整个堆 – 包括年轻代和老年代。

2.2.5 程序计数器(PC寄存器

程序计数器(PC寄存器):存放下一条字节码指令的地址,由执行引擎读取一条字节码指令并转为本地机器指令进行执行。是程序控制流分支循环、跳转、线程恢复)的指示器,只有它不会抛出OutOfMemoryError。每个线程有自己独立的程序计数器,以便于线程在切换回来时能知道一条指令是什么。程序计数器生命周期与线程一致。

2.3 执行引擎

执行引擎:将字节码指令解释/编译对应平台上的本地机器指令。充当了将高级语言翻译机器语言的译者。

执行引擎在执行过程中需要执行什么样的字节码指令依赖于PC寄存器。每当执行完一项指令操作后,PC寄存器就会更新一条需要被执行的指令地址。

指令可以分为字节码指令和本地机器指令。

原文地址:https://blog.csdn.net/qq_40991313/article/details/134742377

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_44622.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注