浅学JVM

一、基本概念

目录

一、基本概念

[二、JVM 运行时内存](#二、JVM 运行时内存)

1、新生代

[1.1 Eden 区](#1.1 Eden 区)

[1.2. ServivorFrom](#1.2. ServivorFrom)

[1.3. ServivorTo](#1.3. ServivorTo)

[1.4 MinorGC 的过程 (复制- >清空- >互换)](#1.4 MinorGC 的过程 (复制- >清空- >互换))

[1.4.1:eden 、servicorFrom 复制到ServicorTo,年龄+1](#1.4.1:eden 、servicorFrom 复制到ServicorTo,年龄+1)

[1.4.2:清空eden 、servicorFrom](#1.4.2:清空eden 、servicorFrom)

[1.4.3:ServicorTo 和ServicorFrom 互换](#1.4.3:ServicorTo 和ServicorFrom 互换)

2、老年代

3、永久代


JVM 是可运行 Java 代码的假想计算机 ,包括一套字节码指令集、一组寄存器、一个栈、 一个垃圾回收, 堆 和 一个存储方法域。 JVM 是运行在操作系统之上的,它与硬件没有直接的交互。

二、JVM 运行时内存

Java 堆从 GC 的角度还可以细分为: 新生代(Eden区、 From Survivor 区和 To Survivor 区)和老年 代。 1、1、

1、新生代

是用来存放新生的对象。 一般占据堆的 1/3 空间。由于频繁创建对象, 所以新生代会频繁触发 MinorGC 进行垃圾回收。新生代又分为 Eden 区、 ServivorFrom、ServivorTo 三个区。

1.1 Eden 区

Java 新对象的出生地 (如果新创建的对象占用内存很大, 则直接分配到老 年代) 。当 Eden 区内存不够的时候就会触发 MinorGC,对新生代区进行 一次垃圾回收。

1.2. ServivorFrom

上一次 GC 的幸存者,作为这一次 GC 的被扫描者。

1.3. ServivorTo

保留了一次 MinorGC 过程中的幸存者。

1.4 MinorGC 的过程 (复制- >清空- >互换)

MinorGC 采用复制算法。

1.4.1:eden 、servicorFrom 复制到ServicorTo,年龄+1

首先, 把 Eden 和 ServivorFrom 区域中存活的对象复制到 ServicorTo 区域(如果有对象的年 龄以及达到了老年的标准,则赋值到老年代区), 同时把这些对象的年龄+1 (如果 ServicorTo 不 够位置了就放到老年区) ;

1.4.2:清空eden 、servicorFrom

然后, 清空 Eden 和 ServicorFrom 中的对象;

1.4.3:ServicorTo 和ServicorFrom 互换

最后, ServicorTo 和 ServicorFrom 互换,原 ServicorTo 成为下一次 GC 时的 ServicorFrom

区。

2、老年代

主要存放应用程序中生命周期长的内存对象。

老年代的对象比较稳定,所以 MajorGC 不会频繁执行。在进行 MajorGC 前一般都先进行 了一次 MinorGC,使得有新生代的对象晋身入老年代,导致空间不够用时才触发。当无法找到足 够大的连续空间分配给新创建的较大对象时也会提前触发一次 MajorGC 进行垃圾回收腾出空间。

MajorGC 采用标记清除算法:首先扫描一次所有老年代,标记出存活的对象,然后回收没 有标记的对象。 MajorGC 的耗时比较长, 因为要扫描再回收。 MajorGC 会产生内存碎片,为了减 少内存损耗, 我们一般需要进行合并或者标记出来方便下次直接分配。当老年代也满了装不下的 时候, 就会抛出 OOM( Out of Memory)异常。

3、永久代

指内存的永久保存区域, 主要存放 Class 和 Meta (元数据) 的信息,Class 在被加载的时候被 放入永久区域 ,它和和存放实例的区域不同,GC 不会在主程序运行期对永久区域进行清理。所以这 也导致了永久代的区域会随着加载的 Class 的增多而胀满,最终抛出 OOM 异常。

三、运行过程

我们都知道 Java 源文件,通过编译器,能够生产相应的.Class 文件, 也就是字节码文件,

而字节码文件又通过 Java 虚拟机中的解释器, 编译成特定机器上的机器码 。

也就是如下:

① Java 源文件--- - >编译器--- - >字节码文件

② 字节码文件--- - >JVM--- - >机器码

每一种平台的解释器是不同的,但是实现的虚拟机是相同的,这也就是 Java 为什么能够 跨平台的原因了 ,当一个程序从开始运行,这时虚拟机就开始实例化了,多个程序启动就会 存在多个虚拟机实例。程序退出或者关闭,则虚拟机实例消亡,多个虚拟机实例之间数据不能共享。

四、线程

这里所说的线程指程序执行过程中的一个线程实体。JVM 允许一个应用并发执行多个线程。 Hotspot JVM 中的 Java 线程与原生操作系统线程有直接的映射关系。当线程本地存储、缓 冲区分配、同步对象、栈、程序计数器等准备好以后, 就会创建一个操作系统原生线程 。 Java 线程结束, 原生线程随之被回收。操作系统负责调度所有线程,并把它们分配到任何可

用的 CPU 上。当原生线程初始化完毕,就会调用 Java 线程的 run() 方法。当线程结束时,

会释放原生线程和 Java 线程的所有资源。

Hotspot JVM 后台运行的系统线程主要有下面几个:

虚拟机线程 (VM thread) 这个线程等待 JVM 到达安全点操作出现。这些操作必须要在独立的线程里执行,因为当 堆修改无法进行时, 线程都需要 JVM 位于安全点。这些操作的类型有: stop-the-

world 垃圾回收、线程栈 dump、线程暂停、线程偏向锁(biased locking)解除。

周期性任务线程--》这线程负责定时器事件(也就是中断), 用来调度周期性操作的执行。

GC 线程--》这些线程支持 JVM 中不同的垃圾回收活动。

编译器线程--》这些线程在运行时将字节码动态编译成本地平台相关的机器码。

相关推荐
静心观复19 分钟前
futures.toArray(new CompletableFuture[0])
java
java66666888829 分钟前
如何在Spring Boot中实现实时通知
java·spring boot·后端
万界星空科技35 分钟前
介绍一款Java开发的商业开源MES系统
java·开发语言·经验分享·科技·5g·开源·制造
振华首席娱记36 分钟前
代码随想录——划分字母区间(Leetcode763)
java·数据结构·算法·leetcode·职场和发展
飞翔的佩奇1 小时前
Java项目:基于SSM框架实现的游戏攻略网站系统分前后台【ssm+B/S架构+源码+数据库+毕业论文+任务书】
java·数据库·spring·游戏·架构·maven·ssm框架
u0104058361 小时前
构建可扩展的Java Web应用架构
java·前端·架构
长亭外的少年1 小时前
ClickHouse 介绍:深度解析高性能列式数据库的核心优势
java·数据库·clickhouse
tokengo1 小时前
从Java开发者到.NET Core初级工程师学习路线:C#语言基础
java·csharp·新人入门
java6666688881 小时前
深入理解Spring Boot中的配置加载顺序
java·spring boot·后端
空青7262 小时前
ChatGPT在Java后端开发中的应用与影响
java·开发语言·人工智能·后端·神经网络·机器学习·chatgpt