JAVA进阶--JVM

一.JVM的概述

java语言有跨平台特点, 写一次java程序,可以在不同的平台上运行.(JVM虚拟机的作用)

       前提条件: 在不同的平台上安装不同的虚拟机(虚拟机就是一个翻译)

.java--->.class--->不同的虚拟机--->机器码

1.jvm作用:

       负责将字节码翻译为机器码, 管理运行时内存

2.jvm的整体组成部分

  类加载系统: 负责将硬盘上的字节码文件加载到内存中(重点)

  运行时数据区: 负责存储运行时各种数据(重点)

  执行引擎: 负责将字节码 转为机器码

  本地方法接口: 负责调用本地方法(非java的方法)

  垃圾回收(重点)

二.类加载系统

1.作用

      负责将硬盘上的字节码文件加载到内存中(运行时数据区中)

2.类什么时候会被加载

(1).在一个类写一个main方法,运行main方法

(2).new 某个类对象时

(3).使用类中的静态成员

(4).使用反射机制时

public class Hello {final static  int num = 10;static  int num1= 10;/*静态代码块在类被加载时自动执行,目前可以看做一个类只被加载一次*/static {System.out.println("类被加载了");}public static void main(String[] args) {System.out.println("111111111");}
}public class TestHello {public static void main(String[] args) throws ClassNotFoundException {//new Hello();//System.out.println(Hello.num);// Class.forName("com.ffyc.javapro.jvm.classloader.Hello");/*创建的是数组对象,数组是Hello类型*/Hello [] hellos = new Hello[10];//只是访问类中的静态常量,类是不加载的,直接返回静态常量值即可System.out.println(Hello.num);//System.out.println(Hello.num1);}
}

3.类加载的过程  (了解)

   加载: 以字节流形式读取文件

   链接: 验证 准备 解析

   初始化: 主要为静态成员变量初始化赋值

4.类加载器

     类加载器就是负责加载类的实践者

     不同的类,是否不同的类加载器加载的

  类加载器分类:

    启动类加载器(引导类加载器),不是用java语言写的,是c/c++写的, 负责加载虚拟机核心的类库

    扩展类加载器 ,是用java语言写的,负则加载jre/lib/ext目录下的类

    应用程序类加载器,是用java语言写的,负责加载程序员写的项目中的类(target/class)

public static void main(String[] args) {//获得类的类加载器
System.out.println(String.class.getClassLoader());//类加载器为null,说明是由启动类加载器加载的String类System.out.println(Hello.class.getClassLoader());//sun.misc.Launcher$AppClassLoader@18b4aac2
System.out.println(Hello.class.getClassLoader().getClass().getClassLoader());//应用程序类加载器的加载器为null}

5.什么是双亲委派机制(重点)

   工作原理:

      当收到类加载任务时,首先委派给上级的类加载器加载,如果上级类加载器还有父级,依次递归,直到最顶级的启动类加载器, 当父级类加载器找到类时,成功返回,

      如果找不到,就委派给子类加载器,如果子类加载器找到后,成功返回,

      如果均未找到,那么就抛出ClassNotFoundException.

7.为什么设计双亲委派机制

      为了安全, 避免了自己定义的类,替换了系统中的核心类

       例如: 自己创建java.lang.String, 结果还是加载的系统中的String类

8.如何打破双亲委派机制

       自定义类加载重写方法打破双亲委派机制

           ①可以自定义类加载器

           ②写一个类 继承 ClassLoader类,

           ③重写findClass();

自己用流将字节码读入,

Class<?> clazz = defineClass(null, bytes, 0, bytes.length);
Object o = clazz.newInstance();//反射机制创建对象//com.ffyc.javapro.jvm.classloader.MyClassLoader@1b6d3586
System.out.println(clazz.getClassLoader());

三.运行时数据区

     当类加载系统把类信息加载到内存后,存储到运行时数据区.

     运行时数据区,根据不同的功能可以分为5个部分:

1.程序计数器

     作用:

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

特点:

  (1).是运行时数据区中空间最小的,运行速度最快的区域

  (2).每个线程都有一个属于自己的程序计数器,是线程私有的,程序计数器生命周期与线程生命                 周期相同.

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

2.虚拟机栈

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

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

特点:

     ①线程私有的,每个线程中调用的方法都在线程对应的虚拟机栈中执行.

     ②栈中存储局部变量

     ③虚拟栈中不存在垃圾回收

         虚拟机栈中会存在内存溢出问题(递归调用太深)

         Exception in thread "main" java.lang.StackOverflowError 栈溢出错误

     ④不同线程中所包含的栈帧(方法)是不允许存在相互引用的

              (eg:A线程中的方法不能调用B线程中的方法)

     ⑤先进后出

public void test(){   int a = 10;//局部变量int b= 20;String s = new  String(); //s是引用类型,保存的是对象地址
}

栈帧:

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

栈帧内部结构:

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

        ②操作数栈    ——    操作数栈就是用来计算的区域,

            例如  :

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

        ③方法返回地址: 记录方法调用的位置,方法执行完成后要回到自己开的位置

3.本地方法栈

       本地方法: 在java程序中,不是用java语言实现的方法, 由底层操作系统提供

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

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

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

特点:

         ①线程私有的,每个线程都有属于自己的本地方法栈

         ②本地方法栈也会出现内存溢出情况

         ③本地方法栈中不会出现垃圾回收

4.堆

(1).概述

       作用:

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

       特点:

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

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

​            堆空间是所有线程共享的.

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

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

(2).堆内存区域划分

新生代(区): 伊甸园区    幸存者0(from)   幸存者1(to)

老年代(区):

(3).为什么要分区(代)

    根据对象的存活周期,对象的大小放在不同的区域,不同的区域可以采用不同的垃圾回收算法.会频繁的回收新生代, 相对较少回收老年代.可以对回收算法扬长避短.

(4).对象创建内存分配过程

      ①.新创建的对象都存储在伊甸园区(比较大的对象,可以直接分配到老年代)

      ②.当下次垃圾回收到来时,把伊甸园区存活的对象移动到幸存者0区,清空伊甸园区

      ③.当下次垃圾回收时,把伊甸园区中存活的对象和幸存者0区的存活对象移动到幸存者1区,清空伊甸园区和幸存者0区.

      ④.当一个对象经历过最大上限15次垃圾回收后,依然存活,那么将此对象移动到老年代

5.方法区

(1).概述

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

         是一个被线程共享的内存区域

         方法的大小也是可以设置的,方法区的大小决定可以加载多少了类

          方法区也是有可能出现内存溢出的.

(2).方法区大小设置

              可以使用参数-XX:MetaspaceSize指定

(3).方法区的垃圾回收

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

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

              ①.该类所创建的对象都已经不再使用,并且被回收了

              ②.该类的Class对象也不在被使用了

              ③.加载该类的类加载器也被回收了

线程共享: 堆,方法

线程私有的: 程序计数器,虚拟机栈,本地方法栈

会出现内存溢出: 堆,方法, 虚拟机栈,本地方法栈

会出现垃圾回收: 堆,方法区

四.本地方法接口 (了解)

       虚拟机中负责调用本地方法的入口, 本地方法运行在本地方法栈中.

什么是本地方法:

       被native修饰的方法, 没有方法体, 是操作系统提供的方法

为什么java中要调用本地方法:

        java属于上层应用开发语言,没有权限直接访问计算机硬件(硬盘,内存,外设(喇叭)),需要调用本地操作系统提供的方法.

五.执行引擎(黑盒)  (了解)

执行引擎在虚拟机中主要负责将加载到虚拟机中的字节码 解释/编译 为机器码

.java-----jdk编译--->.class 在开发阶段 (前端编译)

.class---执行引擎编译---->机器码 在运行阶段(后端编译)

什么是解释器?什么是 JIT 编译器?

   解释器/解释执行--->sql,html,css,js ,python 解释执行 不需要整体编译,由解释器一行一行执行

   JIT编译器-->编译执行,先把代码整体进行编译,生成另一种文件格式,但并不是马上执行

解释执行特点:

           速度慢, 不需要花费时间编译 

编译执行特点:

            编译后执行快, 但是编译需要花费一定的时间

jvm中的执行引擎在将字节码 翻译为机器码时,采取半解释,半编译机制.

开始时,可以先采用解释执行,立即投入到翻译工作中,

等到编译器编译完成后,采用编译执行

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

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

相关文章

基于Alpine构建MySQL镜像

文章目录基于Alpine构建MySQL镜像一、基础镜像选择与初始化1. 基础镜像选型2. 系统初始化二、核心配置构建1. 目录与权限配置2. 配置文件优化三、安全增强配置1. 密码策略强化2. 非root运行四、数据持久化与启动配置1. 数据卷声明2. 入口脚本优化五、完整Dockerfile示例六、关键…

Alamofire 网络请求全流解析,通俗易懂

Alamofire 网络请求全流程解析&#xff1a;从发起请求到处理响应 一、请求发起阶段&#xff1a;准备你的"快递" 1. 你告诉Alamofire要发什么"快递" // 就像告诉快递员&#xff1a;"我要寄一个包裹给https://api.example.com" AF.request("h…

链路聚合技术

链路聚合技术 链路聚合概述及应用场景 概述 链路聚合是把多条物理链路聚合在一起&#xff0c;形成一条逻辑链路。应用在交换机、路由器、服务器间链路&#xff0c;注意了&#xff0c;主机上面不能用链路聚合技术分为三层链路聚合和二层链路聚合链路聚合的作用 增加链路带宽提供…

SpringCloud之Zuul

SpringCloud之Zuul 推荐参考&#xff1a;https://www.springcloud.cc/spring-cloud-dalston.html#_router_and_filter_zuul 1. 什么是Zuul Spring Cloud Zuul 是 Netflix 提供的微服务网关核心组件&#xff0c;作为统一的 API 入口&#xff0c;承担请求路由、过滤、安全控制等…

低精度定时器 (timer_list) 和 高精度定时器 (hrtimer)

Linux 内核提供了两种主要类型的定时器&#xff0c;以满足不同的时间精度需求&#xff1a;低精度定时器 (timer_list) 和 高精度定时器 (hrtimer)。它们各有特点和适用场景。下面&#xff0c;我将分别提供它们在内核代码中的简化使用示例。1. 低精度定时器 (timer_list) 示例ti…

虚拟机VMware的使用方法

虚拟机VMware的使用方法VMware是全球领先的虚拟化技术提供商&#xff0c;其产品&#xff08;如VMware Workstation Pro&#xff09;允许用户在单一物理机上运行多个操作系统&#xff08;OS&#xff09;&#xff0c;实现资源高效利用、隔离测试和灵活部署。本文将详细介绍VMware…

冰岛人(map)

#include<bits/stdc.h> using namespace std; struct people { string fat; int sex; }; map<string,people>mp; int pan(string s,string m) { string s1; int i0; while(s!“”) { int y0; s1m; while(s1!“”) { if(s1s&&(i<4||y<4)) return 0; s…

MS Azure Eventhub 发送 AD log 到cribl

1: 首先说一下,Cribl 提供了很多第三方的接口: 先看一下cribl 提供的接口界面: 注意到,上面提供的link 地址是 xxxxx:9093, 不鼠标放到撒谎给你吗的? 上面,就可以看到了。所以要开的port 一定要把9093 开了,关于全部开的port: What ports do I need to open on the f…

电力名词通俗解析5:计量系统

## 电网计量系统通俗讲解&#xff1a;南网视角下的电力“精算师”想象一下&#xff0c;城市电网如同一个庞大而精密的“能量河流”&#xff0c;千家万户、工厂企业都在从中取水&#xff08;用电&#xff09;。如何精确计量每家用了多少“水”&#xff1f;如何确保“河流”输送中…

关于redis各种类型在不同场景下的使用

Redis 提供了多种数据结构类型,每种类型适用于不同的场景。以下是 Redis 主要数据类型及其典型应用场景的详细说明: 1. String(字符串) 特点:最简单的键值存储,值可以是字符串、整数或二进制数据(最大 512MB)。 适用场景: 缓存:存储用户会话、网页内容等(如 SET u…

Vue 3 动态ref问题

目录 1.问题描述 2.示例代码 3.原因分析 4.解决方案 5.总结 1.问题描述 在Vue 3项目中&#xff0c;当使用动态ref来引用组件时&#xff0c;删除组件后发现ref对象中对应的key仍然存在&#xff0c;只是值变为null&#xff0c;而不是完全删除该key。 在一个可拖拽的卡片列表…

lazyvim恢复gt键

好的&#xff01;下面是一个完整的 LazyVim 键位配置 patch&#xff0c;将 gt / gT 恢复为 “切换标签页&#xff08;tab page&#xff09;” 的原始行为&#xff0c;同时保留原本 buffer 切换功能在其他键位上&#xff08;比如 / &#xff09;。 ⸻ ✅ 恢复 gt 为 Tab 切换&a…

React Native 在 Web 前端跨平台开发中的优势与实践

React Native 在 Web 前端跨平台开发中的优势与实践 对于广大 Web 前端开发者而言&#xff0c;移动端开发似乎总隔着一层“原生”的壁垒。学习 Swift/Kotlin、熟悉 Xcode/Android Studio 的高昂成本&#xff0c;让许多人望而却步。然而&#xff0c;“一次编写&#xff0c;多端运…

QT控件 使用QtServer系统服务实现搭建Aria2下载后台服务,并使用Http请求访问Json-RPC接口调用下载退出

前言 最近了解到qt-solutions这个开源项目,仔细研究一番&#xff0c;发现其中的QtServer项目能在Windows系统中创建系统服务&#xff0c;Linux/Unix系统中能作为守护进程使用&#xff0c;之前一直以为编写服务需要使用Windows api来实现&#xff0c;没想到这么简单。 本来之前就…

Python中关于数组的常见操作

Python中关于数组的常见操作 1.创建数组 array []2.添加元素 array.append()3.访问元素 print(array[2])通过索引进行数组元素的访问 4.修改元素 array[2] 3直接对想修改的元素位置进行赋值 5.删除元素 array.remove(2) #删除元素2del array[2] #删除索引为2的元素6…

Image 和 IMU 时间戳同步

1 目录 时间戳同步介绍 时间戳同步初探 时间戳获取方式 时间戳延迟估计方法 姿态补偿 匀速模型在 Bundle Adjustment 中的应用 重投影残差 视觉特征匀速运动补偿特征坐标 重投影残差 基于特征匀速模型算法的实验结果 轨迹匀速模型 vs 特征匀速模型 时间戳同步算法扩…

创建linux端口映射连接小网

&#x1f680; 方法 1&#xff1a;在执行机上配置 SSH 服务端转发 这个做法是在 执行机上配置一个常驻 SSH 隧道&#xff0c;把大网的某个端口长期转发到小网单板的 22 端口。 &#x1f468;‍&#x1f4bb; 操作步骤 1️⃣ 在执行机上创建一个 systemd 服务 假设&#xff1a; …

了解Java21

目前还没有实操过从java8/java11直接到java17,java21。 先储备下知识点&#xff0c;写一些简单例子&#xff0c;以便后续的实操。 一些新特性&#xff08;java8之后的&#xff09; var变量 和前端js定义变量一样了&#xff0c;var搞定public static void main(String[] args) {…

【代码】基于CUDA优化的RANSAC实时激光雷达点云地面分割

基于CUDA优化的RANSAC实时激光雷达点云地面分割 摘要&#xff1a; 本文介绍了一个高性能的激光雷达&#xff08;LiDAR&#xff09;地面分割项目。该项目基于RANSAC平面估计算法&#xff0c;并通过深度CUDA并行优化&#xff0c;将核心处理时间从近100ms缩短至10ms以内&#xff…

vuex原理以及实现

vuex官方文档 Vuex是什么&#xff1f; Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化 每一个 Vuex 应用的核心就是 store&#xff08;仓库&#xff09;。“stor…