JVM基础知识总结

news2024/9/21 0:46:21

日常工作中接触到的jvm相关的知识,和jvm相关书籍中汇总总结一下jvm相关基础知识,作为对jvm的了解。

文章目录

  • jvm
    • 运行时数据区域
      • 程序计数器
      • java虚拟机栈
      • 堆heap
      • 非堆内存 nonheap
      • 方法区
      • 直接内存 Direct Memory
    • 类加载机制
      • 类的加载过程
      • 类加载器加载过程的详细说明
      • 类加载器分类
      • 双亲委派模型
    • 垃圾回收
      • 什么是垃圾回收?
      • 为什么需要垃圾回收 GC?
      • 垃圾收集算法
      • 时空停顿 stop-the-world
      • 垃圾收集的步骤
      • 常见的垃圾回收器

jvm

jvm -Java virtual machine Java虚拟机。
jdk1.8之前的jvm的结构:
在这里插入图片描述

运行时数据区域

java源代码 编译成 二进制字节码 jvm指令 解释成一条机器码 交给cpu 执行。
在这里插入图片描述

程序计数器

程序计数器 是线程私有。
【作用】: 记住下一条jvm的执行地址
【特点】: 线程私有;jvm中 唯一不会内存溢出的
在这里插入图片描述

java虚拟机栈

java虚拟机栈是线程私有。线程运行时需要的内存空间。java虚拟机栈是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。
每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程
每个线程运行时所需要的内存
每个栈由多个栈帧组成,对应着每次方法调用时所占用的内存
每个线程只能有一个活动栈帧,对应着当前正在执行的那个方法

栈的特点:先进后出
一个栈由多个栈帧组成
在这里插入图片描述

堆heap

通过new关键字创建的对象 都会存储在堆内存中。简单来说堆就是Java代码可及的内存,是留给开发人员使用的。
特点:

  • 线程共享,堆中对象都需要考虑线程安全的问题
  • 有垃圾回收机制

堆内存分配:

-Xms 256m-Xmx 256m

JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;
JVM最大分配的内存由-Xmx指 定,默认是物理内存的1/4。
默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;
空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。
因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。

java堆区内部结构图 :
在这里插入图片描述
对象在刚刚被创建之后是保存在Eden空间区域的,那些长期存活的对象会经由Survivor(幸存者)空间转存到老年代空间区域(Old generation)。当然对于一些比较大的对象(需要分配一块比较大的连续内存空间),则直接进入到老年代区域,这种情况一般在Survivor空间区域内存不足的时候下会发生。
在这里插入图片描述
在这里插入图片描述
内存分配流程:
在这里插入图片描述
堆内存诊断工具:
jps ——查看当前系统中有哪些java进程
jmap——查看堆内存占用情况
jconsole——图形界面,多功能的检测工具,可以连续监测 线程 cpu

非堆内存 nonheap

在JVM中堆之外的内存称为非堆内存(Non-heap memory)
非堆内存分配:

-XX:PermSize 256m-XX:MaxPermSize 256m

VM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;
由-XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

溢出的几种情况

  • 堆溢出: java.lang.OutOfMemoryError:Java heap spcace
  • 栈溢出:java.lang.StackOverflowError
  • 方法区溢出:java.lang.OutOfMemoryError:PermGen space

方法区

方法区是线程共享。存储已被虚拟机加载的类信息、常量、静态变量…

直接内存 Direct Memory

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致OutOfMemoryError异常出现,所以我们放到这里一起讲解。

直接内存oom ——当各个内存区域总和大于物理内存限制,就会导致动态扩展时出现OutOf MemoryError

类加载机制

类的加载过程

虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,
最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。
在Java代码中,类型的加、连接与初始化过程都是在程序运行期间完成的。

JVM将类加载过程分为三个步骤:装载(Load),链接(Link)和初始化(Initialize)链接又分为三个步骤。

虚拟机规范规定的5种必须立即执行初始化的情况:

  • 遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行初始化,则需要先出发初始化 :
    (1) new —— 使用new关键字实力化对象
    (2)getstatic、putstatic——读取或设置一个类的静态字段
    (3) invokestatic——调用一个类的静态方法
  • 使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化
  • 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
  • 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类。

类加载器加载过程的详细说明

在这里插入图片描述

类加载器分类

  • 启动类加载器 bootstrap class loader : 最底层的加载器,由c/c++语言实现。负责加载JDK中的rt.jar文件中的所有java字节码文件。
  • 扩展类加载器 Extension Class Loader ,负责java相关的

双亲委派模型

双亲委派模型的工作过程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。
在这里插入图片描述

垃圾回收

什么是垃圾回收?

运行程序中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。
内存回收时会将已经不再使用的对象实例等从内存中移除掉,以释放出更多的内存空间,这个过程就是常说的JVM垃圾回收机制。
新生代的垃圾回收 —— Minor GC
老年代的垃圾回收 —— Major GC 或者Full GC

为什么需要垃圾回收 GC?

清理堆内存空间,堆内存空间碎片整理,主要对象: java堆 方法区
在这里插入图片描述
垃圾回收之所以如此重要,是因为发生垃圾回收时一般会伴随着应用程序的暂停运行。
一般发生垃圾回收时除GC所需的线程外,所有的其他线程都进入等待状态,直到GC执行完成。
GC调优最主要目标就是减少应用程序的暂停执行时间。

垃圾收集算法

垃圾回收:把垃圾找出来,把垃圾清掉。

垃圾收集算法:

垃圾回收算法说明
根搜索算法采用根搜索算法的垃圾回收线程把应用程序的所有引用关系看作一张图,从一个节点GC ROOT,开始,寻找对应的引用节点,找到这个节点后,继续寻找这个节点的引用节点。当所有的引用节点寻找完毕后,剩余的节点则被认为是没有被引用到的节点,即无用的节点,然后对这些节点执行垃圾回收。
标记清除算法首先标记,在完成标记后统一回收所有被标记过的对象【弱点】:效率低,清除后产生大量不连续的内存碎片
复制算法把可用内存按容量划分为大小相等的两块,每次只使用其中的一块,当把一块内存用完了,就将还存活的对象复制到另一块上面,然后把已使用过的内存空间一次清理掉。
标记整理算法标记-整理算法是在标记-清除算法之上,又进行了对象的移动排序整理,虽然性能成本更高了,但却解决了内存碎片的问题。如果不解决内存碎片的问题,一旦出现需要创建一个大的对象实例时,JVM可能无法给这个大的实例对象分配连续的大内存,从而导致发生Full GC。
增量回收算法增量回收算法把JVM内存空间划分为多个区域,每次仅对其中某一个区域进行垃圾回收,这样做的好处就是减小应用程序的中断时间,使得用户一般不能觉察到垃圾回收器正在工作。

JVM为了优化垃圾回收的性能,使用了分代回收的方式。它对于新生代内存的回收(Minor GC)主要采用复制算法,而对于老年代的回收(Major GC/Full GC),大多采用标记-整理算法。在进行垃圾回收优化时,最重要的一点就是减少老年代垃圾回收的次数,因为老年代垃圾回收耗时长,性能成本非常高,对应用程序的运行影响非常大。

需要特别注意的是,每一种垃圾回收器都会存在用户线程(即用户程序)暂停的问题,只不过每种回收器用户线程暂停的时长优化程度不一样。在启动JVM时,可以通过“指定参数-xx:+垃圾回收器名称”来自定义JVM使用何种垃圾回收器进行垃圾回收。如果未指定的话,JVM将根据服务器的CPU核数和JDK版本自动选择对应的默认垃圾回收器。

时空停顿 stop-the-world

所有应用线程都停止运行所产生的停顿——调优垃圾收集时,要尽量减少这种停顿 是为最关键的因素

垃圾收集的步骤

  • 1.查找不在使用的对象
  • 2.释放这些对象所管理的内存 & 对堆内存布局进行压缩整理

常见的垃圾回收器

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/141928.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里云网络解决方案架构师任江波:全球一张网,支撑游戏业务高效互联

2022 年 8 月 30 日,阿里云用户组(AUG)第 9 期活动在北京举办。活动现场,阿里云网络解决方案架构师任江波,向参会企业代表分享了全球一张网,支撑游戏业务高效互联。本文根据演讲内容整理而成。 在座的很多我…

Web3中文|年度回顾:2022年Web3的发展情况

老生常谈的话题都有一个共同点,那就是它总是包含着一些无趣但至关重要的真理。例如,众所皆知天空是蓝色的,所以大家并不会把它纳入日常讨论,但这并不代表它对物理学、生物学和其他学科而言没有价值。 当我们回望2022年的Web3领域…

docker 部署maven服务器,并将代码发布到maven服务器,并kie-server关联

书接上文 已经搭建好了kie-server的docker swarm集群. 没有搭建business-central是集群是因为这是个页面的可视化的开发环境 一来面向开发人员,不需要集群部署 二来他的数据是放在本地的git服务器上的. 所以每个node的数据不会统一 三来部署好了之后页面也打不开… 四来busines…

推荐系统入门学习(一)【小白入门系列】

推荐系统入门学习(一) 前言:本博客不会采取大量的难懂的语言来介绍推荐系统,只会用一些简单的方式来介绍推荐系统,祝学习愉快! 1、推荐系统的概念 简单的说,推荐系统则是将产品推荐给用户的一…

判断点在多边形内部

一、问题描述已知点P(x,y)和多边形polygon,判断点P(x,y)是否在多边形内部。二、解决方案射线法以点P为端点,向左方作射线L,由于多边形是有界的,所以射线L的左端一定在多边形外部。考虑沿着L从无究远处开始自左向右移动&#xff0c…

Android 更改鼠标样式

定义风格 鼠标风格定义位置&#xff1a;\frameworks\base\core\res\res\values\styles.xml 系统定义了两套鼠标的风格&#xff0c;一套是默认&#xff0c;一套是放大的图标的风格&#xff0c;在下面增加自己的鼠标风格图标 <style name"BluePointer"><ite…

Springboot Controller接口默认自动填充 业务实体参数值

前言 今天看有小伙伴求救&#xff1a; 我还是一贯如此&#xff0c; 有人不明白&#xff0c;没玩过HandlerMethodArgumentResolver 。 那么很可能不止他一个人&#xff0c; 那么我就有必要出手。 不多说&#xff0c;开搞。 正文 快速模拟出这个使用场景 &#xff1a; 假如有好多…

Allegro174版本新功能介绍之动态铜皮Fast模式设置

Allegro174版本新功能介绍之动态铜皮Fast模式设置 Allegro升级到了174版本后,相比于172版本把动态铜皮的FAST模式优化的更为到位,据介绍,铜皮smooth的时间可以缩短非常多,尤其是针对于数据量非常大PCB,效率提升不少,但是在出生产文件的时候,铜皮还是必须Smooth,见下面o…

Odoo 16 企业版手册 - 库存管理之作业类型

作业类型 Odoo库存模块是有效管理所有类型库存操作的最佳选择。为公司的库存管理提供适当的支持对于完美地运营业务至关重要。当我们谈论Odoo是库存管理的完美解决方案时&#xff0c;您会好奇它提供的功能。在本节中&#xff0c;我们将使用专用库存模块详细介绍Odoo管理的库存操…

Vue(七) 生命周期和组件(一)

目录 1. 生命周期 1.1 引出生命周期 1.2 生命周期——挂载流程 1.3 生命周期——更新流程 1.4 生命周期——销毁流程 1.5 总结 2. 非单文件组件 2.1 对组建的理解 2.2 非单文件组件 2.3 组件的注意点 2.4 组件的嵌套 2.5 VueComponent构造函数 1. 生命周期 生命周期…

正版授权|FastStone Image Viewer 图像编辑转换浏览器软件,个人免费的图像浏览器、转换器和编辑器。

前言&#xff1a;快速、稳定、用户友好的图像浏览器、转换器和编辑器。它具有一系列不错的功能&#xff0c;包括图像查看、管理、比较、红眼去除、电子邮件、调整大小、裁剪、修饰和颜色调整。以下是软件页面。 FastStone Image Viewer 是一个快速、稳定、用户友好的图像浏览器…

软件安全测试需要考虑哪些问题?看看专业软件测评中心怎么说

互联网信息时代&#xff0c;软件产品为我们的生活和工作中带来了极大的便利。我们使用的软件都有包含个人资料以及各类信息等安全因素&#xff0c;因此软件的安全问题是用户最为关注的话题之一。可以有效保障软件产品安全的的关键手段便是软件安全测试&#xff0c;那么在进行软…

力扣sql入门篇(九)

力扣sql入门篇(九) 1 股票的资本损益 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # 每个用户的所有Sell的price值减去Buy的price值就可以了 SELECT e.stock_name,sum(e.price) capital_gain_loss FROM ( SELECT stock_name,operation,operation…

解决可见性的方案有哪几种,你都知道吗???

1. 前言 上次【保证原子性的几种方式&#xff0c;你都知道吗&#xff1f;&#xff1f;&#xff1f;】 经过一顿大杂烩后&#xff0c;列举了几种原子性的解决方案。这次我们继续上次的话题&#xff0c;我们来说说可见性的解决方案。废话不多说&#xff0c;让我们赶快开始吧。 2.…

【阶段二】Python数据分析Pandas工具使用10篇:探索性数据分析:数据的检验:正态性检验

本篇的思维导图: 探索性数据分析:数据的检验 数据检索,则是对数据深层次的探索或挖掘,用于验证数据是否服从某种假设,这部分内容将以数据的正态性检验、卡方检验和t检验为例,结合Python讲解具体的使用方法。 正态性检验 统计学中的很多模型或检验都需要…

java旅游日志博客系统旅行记录系统

简介 记录个人旅游动态日志的系统&#xff0c;也可以用来做博客系统&#xff0c;主页可以发布旅游日志&#xff0c;关注博主&#xff0c;给博主留言&#xff0c;管理评论&#xff0c;博文点赞&#xff0c;个人主页。 演示视频 https://www.bilibili.com/video/BV1rv41147W1/?…

(深度学习快速入门)第三章第三节1:深度学习必备组件之数据集处理和参数初始化

文章目录一&#xff1a;数据集的处理&#xff08;1&#xff09;数据集划分&#xff08;2&#xff09;数据集验证&#xff08;3&#xff09;标准化和归一化二&#xff1a;模型参数的初始化&#xff08;1&#xff09;梯度消失和梯度爆炸&#xff08;2&#xff09;模型参数初始化方…

Kafka概述

Kafka入门-1 视频资料&#xff0c;b站&#xff1a;https://www.bilibili.com/video/BV1eD4y1C7uM/?spm_id_from333.788.recommend_more_video.14&vd_source37596bc6f952081640b3f38ea9f6a2cb 深入理解 Kafka: 核心设计与实践原理。PDF 书资料&#xff1a; https://book.…

P8第一讲(选修):反向传播Backpropagation

8. 第 1 讲&#xff08;选修&#xff09;&#xff1a;反向传播_哔哩哔哩_bilibili Gradient Descent neual work基本架构已经学过了 backpropagation(反向传播)可以帮助我们有效的进行渐变迭代计算(帮助计算梯度)。 假设网络有一大堆参数&#xff1a; 首先选一个初始的参数&…

零基础多图详解图神经网络(GNN/GCN)【论文精读】

原文链接&#xff1a; A Gentle Introduction to Graph Neural Networks (distill.pub) 我们不仅仅关系整个图的架构&#xff0c;其实我们更关心的是每个顶点每条边和整个图所表示的信息。 我们如何把我们想要的信息表示成以上这些向量&#xff0c;以及这些向量是否能够通过数据…