当前位置: 首页 > news >正文

JVM的组成

JVM

运行在操作系统之上

java二进制字节码文件的运行环境

JVM的组成部分

java代码在编写完成后编译成字节码文件通过类加载器

来到运行数据区,主要作用是加载字节码到内存

包含

方法区/元空间 堆 程序计数器,虚拟机栈,本地方法栈等等

随后来到执行引擎,主要作用是翻译字节码为底层的系统指令

包含

解释器 即时编辑器 垃圾回收器GC

还有一部分是本地方法接口和本地库

使用原生的C和C++实现

程序计数器

线程私有的,内部保存的字节码的行号

用于记录正在执行的字节码指令的地址

程序计数器

线程私有

每个线程一份保存字节码的行号,用于记录正在执行的字节码指令的执行位置

当分片调度线程时,每次只需要重新从计数器记录的位置继续执行即可

JVM堆

主要用于保存对象的实例和数组等

当堆中内存空间满时,抛出OOM异常

Java内存结构

请添加图片描述

分为年轻代和老年代

年轻代

分为Eden区 S0 S1

一开始对象会进入Eden区,在经历垃圾回收后依然存活就会移向s0,s1最终进入老年代

老年代

主要保存生命周期长的对象

永久代(java8之前)

功能同元空间

保存类信息,静态变量,常量,编译后的代码等

java8以后移至本地内存中,称为元空间

避免堆内存溢出

JVM栈

每个线程运行时所需要的内存,先进后出

每个线程的栈独立,线程安全

每个栈由多个栈帧组成,对应方法调用时占用的内存

每个线程只能有一个活动栈帧,即当前正在执行的方法对应的栈帧

垃圾回收不涉及栈内存,栈帧内存会在弹栈后自动释放
每个栈帧默认为1024k,栈内存大会导致线程数变少,因为每个线程都有自己独立的栈
如果方法内的局部变量没有逃逸出方法外(参数调用或者返回值),方法内的局部变量是线程安全的,因为不同线程调用同一个方法会创建不同栈帧执行

栈内存溢出问题

栈帧过多:递归调用等
栈帧过大

JVM方法区

运行时数据区的一部分

各个线程的共享内存区域
主要存储类的信息和运行时常量池

在hotspot虚拟机中,随虚拟机的开关创建释放

在jdk8之前存在堆中的永久代里

jdk8之后移到了本地内存(操作系统的内存)的元空间中

避免OOM

包括
class
classloader
运行常量池

类似于一张表

主要保存需要执行的类名,方法名,参数类型,字面量等信息

执行机器指令时,会根据符号地址去常量表进行查找得到需要的信息

常量池是.class文件中的,当类被加载时,就会将常量池信息存入运行时常量池

常量池和运行常量池

常量池存在.class字节码文件中,运行常量池

如果方法区中的内存无法满足分配请求,会抛出OOM异常

可以通过-XX:MaxMetaspaceSize=元空间大小m来设置元空间的最大容量

直接内存

不属于JVM中的内存结构,不由JVM进行管理

是虚拟机的系统内存,一般用于NIO操作时用于数据缓存区

分配和回收成本高,但读写性能好

NIO和BIO

BIO:

先切换到内核态,从磁盘中分批次读入系统缓冲区,再从系统缓冲区读入堆内存中的java缓冲区

NIO:

在系统内存中划出一块缓冲区(直接内存),系统和java都可以直接访问

避免了需要读入两次(两块缓冲区)的问题

类加载器

用于将字节码文件(.class文件)装载到运行数据区

主要分为四种

BootStrap ClassLoader

启动类加载器,C++编写,加载java核心库

ExtClassLoader

扩展类加载器,加载扩展jar包

AppClassLoader

应用类加载器,加载开发者自己编写的类

CustomizeClassLoader(不常用)

自定义类加载器,实现自定义类加载规则

类加载器的双亲委派模型

请添加图片描述

加载一个类时,会先委托上一级的加载器进行加载,如果上级加载器也有上级,就会继续向上委托.

如果顶级加载器(启动类加载器)无法加载此类,就会由子加载器进行加载

eg:

test -> AppClassLoader -> ExtClassLoader -> BootStrapClassLoader(无法加载)

回到AppClassLoader加载

String -> AppClassLoader -> ExtClassLoader -> BootStrapClassLoader(可加载)

由启动类加载器加载,其他加载器加载时直接执行即可

双亲委派机制的作用

避免类重复加载,保证唯一性
保证安全,类库API不会被修改

如果定义和核心库中相同的库和类,并自定义方法,就会出现报错

因为启动类加载器已经加载了同名类文件,如果重复加载就会对你自定义的同名类文件报错,防止恶意篡改核心API库

http://www.lryc.cn/news/427648.html

相关文章:

  • 快速上手 iOS Protocol Buffer
  • 每天一个数据分析题(四百八十)- 线性回归建模
  • 电动汽车和混动汽车DC-DC转换器的创新设计与测试方法
  • OriginPro快速上手指南:数据可视化与分析的利器
  • 缓存学习
  • 亚世光电:消费电子年度表演
  • AI 工程应用 建筑表面检测及修复
  • Qt-Qt中的小事项(7)
  • Android MediaRecorder 视频录制及报错解决
  • HarmonyOS应用程序访问控制探究
  • 董卫民赴考拉悠然等企业调研,强调加快发展人工智能产业
  • MFC将类A中的事件在类B中处理采用回调函数实现
  • 公众号 微信登录
  • sanic + webSocket:股票实时行情推送服务实现
  • Unity动态给按钮各个状态下的图片赋值
  • xiaomi pad 6PRO 小米平板6 pro hyperOS降级 澎湃os 降级MIUI 14 教程 免解锁BL 降级,168小时解锁绑定
  • MySQL 备份一个表
  • 鸿蒙开发入门day10-组件导航
  • 虚拟机Linux的坑 | VMware无法从主机向虚拟机 跨系统复制粘贴拖动 文件/文本
  • Chat App 项目之解析(二)
  • 数据结构与算法 - 双指针
  • Python3网络爬虫开发实战(10)模拟登录(需补充账号池的构建)
  • SQL 调优最佳实践笔记
  • Eclipse的使用配置教程:必要设置、创建工程及可能遇到的问题(很详细,很全面,能解决90%的问题)
  • 遗传算法与深度学习实战(4)——遗传算法详解与实现
  • Nginx+Tomcat实现负载均衡、动静分离集群部署
  • 英语学习8月19日
  • 关于windows环境使用nginx的一些性能问题
  • “解决Windows电脑无法投影到其他屏幕的问题:尝试更新驱动程序或更换视频卡“
  • 第10章 无持久存储的文件系统 (2)