JVM学习日志(六) JVM从加载到内存全过程

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: JVM从加载到内存全过程 简述

JVM从加载到内存全过程

文字流程

  1. java代码编写完成后,首先通过jdea/eclipse编译打包称为jar包/war包,其中封装的是.class字节码文件
  2. 接下来使用java-jar启动jvm虚拟机,开启jvm进程
  3. jvm虚拟机接下来使用类加载器来对字节码文件进行加载
    1. 通过双亲委派机制
    2. 优先通过系统类加载器,加载jdk/lib包下面的类
    3. 然后通过extClassLoader进行加载 /ext包下面的类
    4. 最后通过应用程序类加载器,appClassLoader进行加载
    5. 同时类加载器加载类的时候,还涉及到一个破坏型双亲委派机制,通过上下文类加载器来破坏双亲委派机制,叫做上下文类加载器(ContextClassLoader),这种加载机制可以直接强制调用应用程序层加载器,java中涉及到SPI加载的框架基本都使用到了ThreadContextClassLoader
  4. jvm通过类加载器将class文件加载到jvm内存中,需要经历如下几个步骤
    1. 加载,验证,准备,解析,初始化等步骤
    2. 加载步骤:主要是通过类加载器打通jvm内存区域与.class文件的通道
    3. 验证:验证有很多验证方面,主要作用是验证.class文件格式是否符合规范,最简单的有一个魔数验证,及所有的.class文件的二进制文件开头都是CA FE BA BE这八个魔数
    4. 准备:在这一步主要是将.class文件加载到方法区的元空间中,并创建一个.class对象模板,在加载完成之后,在堆内存中创建.class字节码对象,并且给该对象的属性开辟空间以及赋初始值,如果涉及到基本数据类型的常量的话,在这个阶段也会给常量赋值
    5. 解析:在这一步将对象这种的符号引用转换为直接引用
    6. 初始化:在这一步需要将字节码对象中的对象属性直接赋值
  5. 当.class文件加载到内存中后,通过字节码执行引擎来执行相关的代码,字节码执行引擎会将jvm指令翻译成机器码,这里面涉及到解释器和即时编译器两大组件,解释器分为字节码解释器和模板解释器两种
    1. 字节码解释器是逐行进行编译解释,模板解释器是先将整个模板进行编译,然后再执行,前者编译很快,但是整体执行效率比较低,后者编译时间很慢,但是,编译后执行速度很快
    2. 即时编译器一般是和模板解释器配合使用,对热点代码进行跟踪标记,然后将热点代码编译成为模板代码,然后交由模板解释器进行解释执行
  6. 执行时可能会划分多个线程,每个线程都会有一个程序计数器用来标记和记录当前线程执行的指令位置,方便下次继续执行
  7. 每个线程都会有一个对应的虚拟机栈,用来存储当前系统执行的整体流程,每个方法都会以栈帧的形式来存放入虚拟机栈中,而方法中的局部变量都会存放再栈帧中,此时还有一个共享的栈空间叫做本地方法栈,本地方法栈中存储了一些native修饰的C++本地方法,用来直接跟操作系统进行交互
  8. 虚拟机栈的栈帧中的局部变量只是一个地址值,这个地址值指向的是堆内存中的一个对象地址
  9. 堆空间中分为这几块区域:新生代,老年代,新生代中又包含eden,suvivor0,suvivor1,垃圾处理器GC,youngGC,FullGC
  10. youngGC的触发时机是当新生代的eden区内存满了,放不下新对象的时候,这时候会将没有引用指向的对象清除,然后,将幸存下来的对象存放入suvivor区,并且进行年龄标记,当新生带位置放不下的情况下,会直接将该对象放入到老年代,老年代放不下的时候会直接触发fullGC,FullGC其实也叫Stop All The World,会将整个程序停止,然后进行清除
  11. 再1.8之前方法区中的字符串常量池是存放再老年代中,只有fullGC才会触发清除机制,1.8之后,将字符串常量池存放再新生代eden区中,通过minorGC和youngGC来进行清除

流程图

image-20230423172921088.png

image-20230423173026434.png

image-20230423173103342.png

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
3月前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
609 1
|
2月前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
2月前
|
存储 安全 Java
JVM加载过程
JVM类加载过程是Java开发中的关键环节,主要包括五个阶段:加载、验证、准备、解析和初始化。加载阶段获取类的二进制字节流;验证确保字节码符合规范;准备为静态变量分配内存并默认初始化;解析将符号引用转为直接引用;初始化执行静态变量赋值和静态代码块。了解这一过程有助于深入理解Java程序运行机制,提升编程水平。
|
3月前
|
Java
JVM内存参数
-Xmx[]:堆空间最大内存 -Xms[]:堆空间最小内存,一般设置成跟堆空间最大内存一样的 -Xmn[]:新生代的最大内存 -xx[use 垃圾回收器名称]:指定垃圾回收器 -xss:设置单个线程栈大小 一般设堆空间为最大可用物理地址的百分之80
|
3月前
|
Java
JVM运行时数据区(内存结构)
1)虚拟机栈:每次调用方法都会在虚拟机栈中产生一个栈帧,每个栈帧中都有方法的参数、局部变量、方法出口等信息,方法执行完毕后释放栈帧 (2)本地方法栈:为native修饰的本地方法提供的空间,在HotSpot中与虚拟机合二为一 (3)程序计数器:保存指令执行的地址,方便线程切回后能继续执行代码
38 3
|
3月前
|
存储 缓存 监控
Elasticsearch集群JVM调优堆外内存
Elasticsearch集群JVM调优堆外内存
72 1
|
3月前
|
Arthas 监控 Java
JVM进阶调优系列(9)大厂面试官:内存溢出几种?能否现场演示一下?| 面试就那点事
本文介绍了JVM内存溢出(OOM)的四种类型:堆内存、栈内存、元数据区和直接内存溢出。每种类型通过示例代码演示了如何触发OOM,并分析了其原因。文章还提供了如何使用JVM命令工具(如jmap、jhat、GCeasy、Arthas等)分析和定位内存溢出问题的方法。最后,强调了合理设置JVM参数和及时回收内存的重要性。
|
3月前
|
存储 监控 Java
JVM进阶调优系列(8)如何手把手,逐行教她看懂GC日志?| IT男的专属浪漫
本文介绍了如何通过JVM参数打印GC日志,并通过示例代码展示了频繁YGC和FGC的场景。文章首先讲解了常见的GC日志参数,如`-XX:+PrintGCDetails`、`-XX:+PrintGCDateStamps`等,然后通过具体的JVM参数和代码示例,模拟了不同内存分配情况下的GC行为。最后,详细解析了GC日志的内容,帮助读者理解GC的执行过程和GC处理机制。
|
4月前
|
缓存 监控 Java
在使用 Glide 加载 Gif 动画时避免内存泄漏的方法
【10月更文挑战第20天】在使用 Glide 加载 Gif 动画时,避免内存泄漏是非常重要的。通过及时取消加载请求、正确处理生命周期、使用弱引用、清理缓存和避免重复加载等方法,可以有效地避免内存泄漏问题。同时,定期进行监控和检测,确保应用的性能和稳定性。需要在实际开发中不断积累经验,根据具体情况灵活运用这些方法,以保障应用的良好运行。
|
4月前
|
存储 算法 Java
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。

热门文章

最新文章