学习JVM

java虚拟机
流程:helloworld.java----(javac编译)----helloworld.class-------(java运行)——JVM——机器码

JVM功能
*解释和运行
*内存管理
*即时编译(跨平台-慢一点)jit
        (反复用到的代码 解释保存再内存里面)

jvm主要组成:
*类加载器,
*运行时数据区(jvm管理的内存),
*执行引擎(即时编译器,解释器,垃圾回收器)

字节码文件组成
 

工具:notepad++是不可以的 工具用 jclasslib

组成:基本信息常量池,字段,方法,属性

基本信息
       1, magic(魔数):确认是字节码文件(前缀固定0xcofe base)
        2,主版本号 : (-44就等于jdk)-可以确定运行jdk和编译的版本是否一致

常量池
       
避免重复内容的重复定义,浪费空间
        *常量池的数据都有一个编号
        *字节码指令中提高编号引用常量池的过“符合引用”
方法

JVM:堆,栈,方法区
是线程用的,(后进先出)(执行完就会释放)
        *有多个栈帧组成,对应着每次方法调用时所占的内存
        *每个线程只能有一个活动栈帧,对应正在执行的方法
        递归会导致栈溢出

一个线程一个栈,一个方法一个栈帧

JVM调优

栈和栈帧


程序启动 在jvm的加载机制
1,将代码加载到 方法区(类加载)
2,栈启动mian主线程:  然后给线程的方法分配栈帧
      new出来的对象放堆,方法执行完栈帧就会释放

!!!!
1线程启动就会分配栈,和
程序计数器
2执行方法就会右栈帧(线程的栈帧是独立的)
3方法执行完栈帧就会释放,线程执行完栈就释放

程序计数器: *记录每个线程的执行到哪里-记录当前线程的状态-线程独有的)多线程切换用的
                     
   *由字节码执行引擎修改里面的内容
多线程的时候 操作系统的任务调度器 分配时间片

栈帧存的数据
        1局部变量表(int = 1等)
        2操作数栈(加减乘除操作时的数据空间,计算完就释放)
        3动态链接、(每个方法内存地址,映射 元空间/方法区)
        4方法出口(方法执行完 要继续执行main方法的下一个)



:new出来的对象---公共

栈(线程):放线程的--私有
        
栈里面的对象(保证地址)是指向堆的
本地方法栈:(用native修饰的方法-底层是用C++实现的)--私有  
                
Thread类的本地方法  System类的本地方法

方法区(元空间):常理,静态变量,类信息---公共
        方法区的对象也是指向堆的

JDK诊断工具

*Java VisualVM是JDK自带的基本调优工具之一
*jdk自带诊断命令
*arthas(阿里巴巴)诊断工具 
        。可以快速点位cpu高代码
        。可以快速点位锁代码
        。线上运行代码反编译

JVM堆的组成


1. 新生代(Young Generation):新生代是堆的一部分,用于存储新创建的对象。它又分为Eden区、Survivor区(通常有两个)。
   - Eden区:新创建的对象首先分配在Eden区。
   - Survivor区:当Eden区满时,存活的对象会被移到Survivor区。Survivor区一般有两个,分别称为From区和To区。存活的对象会在From区和To区之间进行复制,经过多次垃圾回收后(每次年龄+1),仍然存活的对象会被移动到老年代(15岁/6 CMS)。
2. 老年代(Old Generation):老年代用于存储长时间存活的对象。当对象经过多次垃圾回收后仍然存活,它们会被移动到老年代。(full GC老年代也回收
对象年龄判断机制(如果对象大于Survivor 50%会直接放老年代)
3. 永久代(Permanent Generation):永久代用于存储类的元数据(metadata)和方法信息(method information)。在JDK 8之后,永久代被元空间(Metaspace)所取代。元空间不再位于堆中,而是位于本地内存中。
4. 堆外内存(Off-Heap Memory):堆外内存是指不受JVM堆管理的内存,通常由本地方法直接分配和释放。堆外内存包括直接内存(Direct Memory)和本地内存(Native Memory)。
 需要注意的是,JVM的堆大小可以通过启动参数进行配置,例如-Xmx和-Xms参数用于设置堆的最大和初始大小。堆的大小对于应用程序的性能和内存使用有重要影响,需要根据具体应用场景进行合理配置。


堆-对象直接进入老年代

1,动态年龄判断:survivor从小到大累加年龄超过空间的50%(默认) ,后面的会直接晋升老年代

2 ,大对象直接接入 大对象就是需要大量连续内存空间的对象(比如:字符串、数组)。
复制很耗性能,
JVM参数XX:PretenureSizeThreshold 可以设置大 对象的大小,如果对象超过设置大小会直接进入老年代,不会进入年轻代,这个参数只在 Serial 和ParNew两个收集器下 有效。比如设置JVM参数:
-XX:PretenureSizeThreshold=1000000 (单位是字节) -XX:+UseSerialGC ,再执行下上
面的第一 个程序会发现大对象直接进了老年代 
为什么要这样呢?(原因) 
为了避免为大对象分配内存时的复制操作而降低效率
(解决——加大Survivor区,并用G1分代收集)
3,
老年代空间担保机制
 


 From区和To区的作用如下:
1. 存储存活对象:在Minor GC过程中,存活的对象会被移动到Survivor区的From区。
2. 进行对象复制:在下一次Minor GC之前,存活的对象会从From区复制到To区。
3. 清空From区:复制完成后,From区会被清空,为下一次Minor GC做准备。
4. 交换From区和To区:在下一次Minor GC时,From区和To区会互换角色,即From区变为To区,To区变为From区。
 通过交替使用From区和To区,Survivor区可以实现对象的复制和清理,以进行有效的垃圾回收。这种复制算法被称为"标记-复制"(Mark and Copy)算法,它可以有效地处理新生代中的对象,并减少内存碎片化的问题。
 需要注意的是,Survivor区的大小可以通过JVM参数进行调整,以适应不同应用程序的需求。一般来说,Survivor区的大小应该合理设置,避免过小导致频繁的对象复制,或过大导致浪费内存空间。

垃圾回收

Minor GC 和 Full GC 垃圾回收会导致 stw(Stop the World")这个系统停顿

        为什么要这样设计:不停止用户线程里面对象就会不断变化,实现简单,

JVM的可达性分析

JVM的可达性分析(Reachability Analysis)是垃圾回收的一种核心算法,用于确定哪些对象是可达的(reachable)或不可达的(unreachable),从而确定哪些对象应该被回收。
可达性分析的基本原理是从一组称为"GC Roots"的根对象开始,通过遍历对象引用链,标记所有与根对象直接或间接相连的对象为可达对象。而未被标记的对象则被认为是不可达的,即无法通过任何引用链访问到的对象。这些不可达对象将被垃圾回收器识别并回收,释放其占用的内存空间。
GC Roots包括以下几种类型的对象:
1. 虚拟机栈(VM Stack)中的引用对象。
2. 方法区(Method Area)中类静态属性引用的对象。
3. 方法区中常量引用的对象。
4. 本地方法栈(Native Method Stack)中JNI引用的对象。
通过从GC Roots出发进行可达性分析,JVM可以确定哪些对象是活动的,即仍然被引用和使用的对象,而哪些对象是不再使用的,可以被回收的对象。
可达性分析是现代垃圾回收器中常用的算法,它具有高效、准确的特点,并能够处理复杂的对象引用关系。通过可达性分析,JVM可以自动管理内存,释放不再使用的对象,从而提高系统的性能和资源利用率。

Minor GC

Minor GC(Minor Garbage Collection)是Java虚拟机(JVM)中的一种垃圾回收操作,主要针对新生代进行回收。新生代是Java堆内存中的一部分,用于存储新创建的对象。Minor GC的目标是清理新生代中的无用对象,以释放内存空间。
 在Minor GC过程中,垃圾回收器会扫描新生代中的对象,并标记那些仍然存活的对象。然后,它会将存活的对象复制到Survivor区(通常是From区),同时清理掉无用的对象。在复制过程中,存活的对象会被移动到Survivor区的To区。最后,From区会被清空,为下一次垃圾回收做准备。
 Minor GC通常发生在新生代中的Eden区(新对象的分配区域)空间不足时。当Eden区满了之后,会触发Minor GC来回收无用的对象,以便为新对象腾出空间。通常情况下,大部分对象在新生代中很快被回收,只有少部分对象会进入老年代(Old Generation)。
 相比于Full GC(Full Garbage Collection),Minor GC的开销较小,回收的对象数量也较少。因此,Minor GC的执行时间通常较短,对应用程序的停顿时间影响较小。它是Java堆内存中垃圾回收的常见操作之一,用于保证新生代的内存空间的有效利用。

Full GC

Full GC(Full Garbage Collection)是Java虚拟机(JVM)中垃圾回收的一种操作,它是对整个堆内存进行回收的过程。Full GC会清理整个堆内存中的所有对象,包括年轻代和老年代。
Full GC通常是在进行一次完整的垃圾回收之前执行的,目的是回收所有不再被引用的对象,释放内存空间。Full GC的执行会导致应用程序的停顿,因为在此期间,所有的应用线程都会被暂停,直到垃圾回收完成。
Full GC通常发生在以下情况下:
1. 当堆内存空间不足时(如老年代太多),无法分配新的对象时,会触发Full GC来回收内存。
2. 当执行System.gc()方法或者调用Runtime.getRuntime().gc()方法时,可能会触发Full GC。
3. 当永久代(Permanent Generation)空间不足时(在JDK 8及之前的版本中),会触发Full GC来回收永久代。
Full GC的执行时间通常比部分垃圾回收(如年轻代的Minor GC)更长,并且会导致较长的停顿时间。因此,对于性能敏感的应用程序,需要合理配置堆内存大小,以减少Full GC的频率和影响。
总之,Full GC是Java虚拟机中对整个堆内存进行的垃圾回收操作,它会清理整个堆内存中的所有对象,包括年轻代和老年代,通常会导致较长的停顿时间

JVM中常见的垃圾回收算法和策略包括以下几种:


1. 标记-清除算法(Mark and Sweep):该算法分为两个阶段,首先标记所有活动对象,然后清除未标记的对象。但是,标记-清除算法会产生内存碎片,可能会导致内存分配效率降低。
2. 复制算法(Copying):该算法将堆内存划分为两个相等大小的区域,每次只使用其中一个区域。当一个区域满时,将存活的对象复制到另一个区域,然后清除当前区域中的所有对象。复制算法消耗的时间较短,但会浪费一部分内存空间。
3. 标记-压缩算法(Mark and Compact):该算法首先标记所有活动对象,然后将活动对象向一端移动,最后清理掉边界以外的内存空间。标记-压缩算法消除了内存碎片,但可能会导致对象移动的开销较大。
4. 分代收集算法(Generational Collection):该算法根据对象的生命周期将堆内存划分为不同的代(Generation),如新生代(Young Generation)和老年代(Old Generation)。新生代中的对象生命周期较短,采用复制算法;而老年代中的对象生命周期较长,采用标记-压缩算法。
5. 并发标记清除算法(Concurrent Mark and Sweep):该算法允许垃圾回收器与应用程序并发执行,减少停顿时间。它通过在标记和清除阶段之间允许应用程序继续运行来提高性能。
6. G1收集器(Garbage-First Collector):G1收集器是一种面向服务端应用的垃圾回收器,它将堆内存划分为多个大小相等的区域(Region),通过并发标记、并发清除和并发整理来实现高效的垃圾回收。
这些垃圾回收算法和策略的选择取决于应用程序的性能需求和内存特点。JVM根据实际情况自动选择适当的垃圾回收器和算法来管理内存。

垃圾收集器

G1(Garbage First)收集器是Java虚拟机(JVM)中的一种垃圾收集器。它在JDK 7u4版本中首次引入,并在JDK 9及以后的版本中成为默认的垃圾收集器。G1收集器采用了分代收集和并发标记整理的方式,旨在提供可预测的停顿时间和高吞吐量的垃圾收集性能。
 G1收集器的主要特点和优势包括:
 1. 分代收集:G1收集器将堆内存划分为多个大小相等的区域(Region),每个区域可以是Eden区、Survivor区或Old区。这种分代的方式可以更好地适应不同对象的生命周期和内存使用模式。
 2. 并发标记:G1收集器使用并发标记算法,在垃圾收集过程中,可以与应用程序线程并发执行标记阶段,减少垃圾收集对应用程序的影响。
 3. 空闲区域优先回收:G1收集器的名字“Garbage First”即表示它优先回收垃圾最多的区域。这种策略可以最大程度地回收垃圾,提高垃圾收集的效率。
 4. 可预测的停顿时间:G1收集器通过将堆内存划分为多个区域,并使用增量式的并发标记算法,可以控制垃圾收集的停顿时间。这对于要求低延迟的应用程序非常重要。
 5. 自适应调节:G1收集器会根据堆内存的使用情况和垃圾收集的效果,动态地调整各个阶段的参数,以达到最优的垃圾收集性能。
 G1收集器适用于大内存、多核处理器的应用场景,尤其是需要低延迟和高吞吐量的服务端应用程序。它在处理大堆内存和大量对象时表现出色,并且可以通过调整参数来满足不同应用程序的需求。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

anolisos8.8安装显卡+CUDA工具+容器运行时支持(containerd/docker)+k8s部署GPU插件

anolisos8.8安装显卡及cuda工具 一、目录 1、测试环境 2、安装显卡驱动 3、安装cuda工具 4、配置容器运行时 5、K8S集群安装nvidia插件 二、测试环境 操作系统:Anolis OS 8.8 内核版本:5.10.134-13.an8.x86_64 显卡安装版本:525.147.05 c…

【docker】docker入门与安装

Docker 一、入门 Docker的主要目标是:Build, Ship and Run Any App, Anywhere,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP及其运行环境能做到一次镜像,处处运行。 Docker运行速度快的原因 Docker有比虚拟…

Spark编程实验一:Spark和Hadoop的安装使用

一、目的与要求 1、掌握在Linux虚拟机中安装Hadoop和Spark的方法; 2、熟悉HDFS的基本使用方法; 3、掌握使用Spark访问本地文件和HDFS文件的方法。 二、实验内容 1、安装Hadoop和Spark 进入Linux系统,完成Hadoop伪分布式模式的安装。完成Ha…

Ignoring query to other database

登录数据库执行查看database的脚本提示 仔细观察才发现,登录的时候我写的是,没写 -u 退出重新登录,好了~

死锁的预防、避免、检测和消除

一、预防死锁 1. 破坏互斥条件 2. 破坏不剥夺条件 3.破坏请求和保持条件 4.破坏循环等待条件 二、避免死锁 避免死锁的一种方法是使用银行家算法,它涉及到安全序列的概念。银行家算法是一种资源分配和死锁避免的算法,它确保系统能够分配资源而不会导致死…

c/c++ 结构体、联合体、枚举

结构体 结构体内存对齐规则: 1、结构体的第一个成员对齐到结构体变量起始位置偏移量为0的地址处 2、其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数:编译器默认的一个对齐数与该成员变量大小的较小值。 vs 中…

JMeter下载与安装

文章目录 前言一、安装java环境(JDK下载与安装)二、JMeter下载三、JMeter安装1.解压缩2.配置环境变量 四、JMeter启动(启动成功则代表JMeter安装成功)五、JMeter汉化(将JMeter修改成中文)1.方法一&#xff…

浅谈5G基站节能及数字化管理解决方案的设计与应用-安科瑞 蒋静

截至2023年10月,我国5G基站总数达321.5万个,占全国通信基站总数的28.1%。然而,随着5G基站数量的快速增长,基站的能耗问题也逐渐日益凸显,基站的用电给运营商带来了巨大的电费开支压力,降低5G基站的能耗成为…

用Bat文件调用小牛翻译api快速翻译

为了帮助大家更加轻松地调用机器翻译api,本人探索实现了一种可以通过BAT文件来调用机器翻译api,对粘贴板中的文本进行翻译,并将翻译结果保存为txt文件。下面把实现步骤简要说明如下: 第一步:获取小牛机器翻译api 进入…

【Spring Boot】内网穿透实现远程调用调试

文章目录 1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 windows系统2.1.2 linux系统 2.2 创建隧道映射本地端口2.3 测试公网地址 3. 固定公网地址3.1 保留一个二级子域名3.2 配置二级子域名3.2 测试使用固定公网地址 4.…

记录hive/spark取最新且不为null的方法

听标题可能听不懂我想表达的意思,我来描述一下我要做的事: 比如采集同学对某一网站进行数据采集,同一个用户每天会有很多条记录,所以我们要取一条这个用户最新的状态,比如用户改了N次昵称,我们只想得到最后…

unity中:搭建在线AR应用

使用Imagine WebAR - Image Tracker插件部署WebGL应用 在使用Imagine WebAR - Image Tracker插件进行WebGL应用开发时,有两个关键知识点需要掌握: 1. 部署到支持HTTPS的服务器 由于WebGL应用需要访问用户的摄像头,因此必须在支持HTTPS的服…

人工智能与数据分析:新时代的趋势和机会

目录 写在开头1. 融合AI和数据分析的趋势1.1 趋势变化1.2 数据驱动目标转换 2 对数据分析行业的影响2.1 技能需求2.2 工作流程和角色的变化2.3 创新和业务驱动的数据分析 3.场景变化3.1 场景1:智能决策支持系统3.1.1 智能决策支持系统的架构设计3.1.2 Python代码演示…

Linux 常用命令----mktemp 命令

文章目录 基本用法实例演示高级用法注意事项 mktemp 命令用于创建一个临时文件或目录,这在需要处理临时数据或进行安全性测试时非常有用。使用 mktemp 可以保证文件名的唯一性,避免因文件名冲突而导致的问题。 基本用法 创建临时文件: 命令 mktemp 默认…

多表查询、事务、索引

目录 数据准备 分类 内连接 外连接 子查询 事务 四大特性 索引 数据准备 SQL脚本: #建议:创建新的数据库 create database db04; use db04;-- 部门表 create table tb_dept (id int unsigned primary key auto_increment comment 主键…

mysql:在字符串类型的列上创建索引,建议指定索引前缀长度

https://dev.mysql.com/doc/refman/8.2/en/create-index.html#create-index-column-prefixes 在字符串类型的列上创建索引,建议指定索引前缀长度,而没有必要用整个列来创建索引。因为用前面的字符创建索引,查询时并不会比在整列上创建索引慢很…

【玩转TableAgent数据智能分析】利用TableAgent进行教育数据分析

文章目录 前言九章云极(DataCanvas)介绍前期准备样例数据集体验1. 样例数据集-Airbnb民宿价格&评价 体验1.1 体验一1.2 体验二 教育数据的分析(TableAgent&ChatGLM对比)1. 上传文件2. 数据分析与对比2.1 分析一2.1.1 Tabl…

SuperMap iClient3D for Cesium 实现鼠标移动选中模型并显示模型对应字段

SuperMap iClient3D for cesium 实现鼠标移动选中模型并显示模型对应字段 一、实现思路二、数据制作1. 计算出模型中心点并保存到属性表中2. 计算出模型顶部高程3. 模型数据切缓存4. 发布三维服务. 三、代码编写 作者:xkf 一、实现思路 将模型属性数据存储到前端&a…

《Kotlin核心编程》笔记:面向对象

kotlin 中的类 // Kotlin中的一个类 class Bird {val weight: Double 500.0val color: String "blue"val age: Int 1fun fly() { } // 全局可见 }把上述代码反编译成Java的版本,然后分析它们具体的差异: public final class Bird {privat…

视觉学习笔记12——百度飞浆框架的PaddleOCR 安装、标注、训练以及测试

系列文章目录 虚拟环境部署 参考博客1 参考博客2 参考博客3 参考博客4 文章目录 系列文章目录一、简单介绍1.OCR介绍2.PaddleOCR介绍 二、安装1.anaconda基础环境1)anaconda的基本操作2)搭建飞浆的基础环境 2.安装paddlepaddle-gpu版本1)安装…