【Java】快速入门JVM

简介: 【Java】快速入门JVM

1. JVM简介

JVM(Java虚拟机)是一个名字为Java的进程,是用于执行Java程序的虚拟机。


JVM会从操作系统中申请一大块内存空间,又把这个内存空间划分成为几个小的区域


区域的划分:


1.堆

2.方法区

3.栈(Java虚拟栈和本地方法栈)

4.程序计数器

5.运行时常量池

代码中的局部变量是放在栈上的,成员变量放在堆上,静态变量放在方法区中,程序计数器放的是下一个要执行的指令地址


一个JVM进行中,堆和方法区只有一份,单栈和程序计数器,每个线程都有自己的一份


补充: 方法区的概念是jdk1.8之前的叫法,而jdk1.8之后没有方法区了,而多了个元数据区.


方法区是JVM申请内存中划分出的一个区域,而元数据区时是用的本地内存


2. 类加载简介

类加载是JVM将类的字节码加载到内存中,并进行验证、准备和解析的过程。也就是源代码(.java)文件编译成字节码文件(.class)


3. 类加载的过程

类加载的过程大致分为以下几步:


1.加载

2.加载

验证

准备

解析

3.初始化

加载:加载是将类的字节码文件加载到内存中的过程。


验证:验证是确保类的字节码符合Java虚拟机规范的过程。


准备: 给类中的静态变量分配内存空间


解析: 初始化字符串常量,把符号引用(占位符)替换成直接引用(内存地址)


初始化:初始化是执行类的初始化代码的过程。


什么时候进行类加载呢?


使用到一个类的时候,就触发类加载(类不一定是程序已启动就加载了,第一次使用时才加载),有点类似于"懒汉模式"


4. 双亲委派

双亲委派是Java类加载器的一种机制,用于保证类的加载安全和避免重复加载。


在讲双亲委派之前,先来了解类加载器


Java类加载器主要有以下几种类型:


启动类加载器(Bootstrap Class Loader):它是JVM的内置类加载器,负责加载Java标准库中的类

扩展类加载器(Extension Class Loader):它是Java平台提供的标准类加载器之一,用于加载Java扩展库(如javax包中的类)和Java虚拟机的扩展部分。

应用程序类加载器(Application Class Loader):也称为系统类加载器(System Class Loader),它是加载应用程序类的默认加载器。应用程序类加载器加载应用程序类路径上的类,即开发人员编写的类和第三方类库。

上述三个类加载器存在父子关系,启动类加载器是扩展类加载器的父类,扩展类加载器是应用程序类加载器的父类


进入类加载的时候,输入的内容是全限定类名,加载的时候从Application Class Loder开始. 即当一个类加载器收到加载类的请求时,它会先委派给父类加载器,只有在父加载器找不到该类的情况下,才会自己加载。如果一直找到最下面的"Application Class Loder"也没有找到,就会抛出一个"类没找到"这样的异常


按照这个顺序的加载最大的好处就是如果子定义的类和Java标准库的类冲突了,此时仍然保留类加载可以加载到标准库中的类


5. GC垃圾回收

GC垃圾回收是Java虚拟机(JVM)自动管理内存的过程。它通过自动识别和回收不再使用的对象,释放内存资源,并提供了内存管理的机制,使开发人员无需手动进行内存释放。


在学习C语言时,有个关键字叫 malloc(动态内存申请),它的内存释放时机是不确定的,需要使用的free进行释放.如果不进行free,这个内存就会一直持续到程序结束. 如果忘记释放,就可能会造成"内存泄漏"


而在Java中,当对象不再被引用时,它们变成了垃圾。垃圾回收器负责扫描程序的内存,找出这些不再被引用的对象,并将它们的内存空间回收,以便后续的对象可以使用。


GC垃圾回收机制基本上可以把内存泄漏问题解决的差不多,但GC也并不是完美的,GC有个STW(stop the world)问题


STW指的是垃圾回收过程中,应用程序的执行被暂停停止的情况。在STW期间,所有的应用线程都会被挂起,直到垃圾回收完成。


STW问题可能会对应用程序的性能和响应时间产生影响,特别是在大型内存或高并发场景下。应用程序的执行会被中断,可能导致暂停时间较长,从而影响系统的实时性和用户体验。


GC垃圾回收主要会受到是哪些内容呢? 答案是堆,且GC中回收内存,不是以"字节"为单位进行回收的,而是以"对象"为单位回收.


GC怎么判断某个对象是否是垃圾呢?


假设有一个对象,如果已经没有任何引用能够指向它了,说明对象自然就无法再被使用了


两种典型的判定对象是否存在引用的方法:


1.引用计数(不是JVM采取的办法)

引用计数的优点: 简单,容易实现,执行效率比较高

引用计数的却嗲: 空间利用率低,可能会出现循环引用的情况

2.可达性分析(JVM采取的办法)

在Java中,GC通过根对象作为起点,查找所有与根对象直接或间接相连的对象,这些对象被称为可达对象,它们是程序中仍然被引用的对象。与根对象没有引用链相连的对象被认为是不可达的,它们将被垃圾回收器标记为可回收的对象。


6. JVM的回收方式

共有以下几种方式:


1.标记清除: 标记-清除是最基本的垃圾回收算法。它分为两个阶段:标记阶段和清除阶段。在标记阶段,垃圾回收器标记所有可达的对象,将其标记为存活对象。在清除阶段,垃圾回收器清除未被标记的对象,释放它们占用的内存空间。

2.复制算法:将内存分为两个区域,一次只使用其中一个区域。在对象存活后,将其复制到未使用的区域中,然后清除旧区域中的所有对象。复制算法适用于对象存活率较低的场景,因为需要较大的内存空间来进行复制。

3.标记整理: 标记-整理算法结合了标记-清除和复制算法的特点。它首先标记所有可达对象,然后将存活对象向一端移动,并清除未移动的内存空间。标记-整理算法适用于对象存活率较高的场景。

7. 分代回收

上述三种方式,虽然都可以实现GC回收,但都会存在一些问题. 因此在使用时,就需要根据不同的场景,采取不同的策略.

所以有引入的一个新的垃圾回收机制-“分代回收”


分代回收:分代算法是基于对象生命周期的假设,将内存分为不同的代,一般分为新生代和老年代。新生代中的对象生命周期短暂,采用复制算法进行回收;而老年代中的对象生命周期较长,采用标记-清除或标记-整理算法进行回收。分代算法适用于大部分应用程序,因为对象的生命周期通常是不同的。


新生代的对象被GC扫描的概率低,老年代的对象被GC的扫描率低. 新生代只有熬过多次GC的扫描,没有被回收,才会进入老年代

注: 如果对象是一个特别大的对象,会直接进入老年代


文章到这就结束了,感谢您的观看!

a6c9a15df4e9486cb7246b4d4e899856.gif



相关文章
|
3月前
|
存储 算法 Java
惊!Java程序员必看:JVM调优揭秘,堆溢出、栈溢出如何巧妙化解?
【8月更文挑战第29天】在Java领域,JVM是代码运行的基础,但需适当调优以发挥最佳性能。本文探讨了JVM中常见的堆溢出和栈溢出问题及其解决方法。堆溢出发生在堆空间不足时,可通过增加堆空间、优化代码及释放对象解决;栈溢出则因递归调用过深或线程过多引起,调整栈大小、优化算法和使用线程池可有效应对。通过合理配置和调优JVM,可确保Java应用稳定高效运行。
140 4
|
1月前
|
Java
jvm复习,深入理解java虚拟机一:运行时数据区域
这篇文章深入探讨了Java虚拟机的运行时数据区域,包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区、元空间和运行时常量池,并讨论了它们的作用、特点以及与垃圾回收的关系。
62 19
jvm复习,深入理解java虚拟机一:运行时数据区域
|
1月前
|
存储 SQL 小程序
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
这篇文章详细介绍了Java虚拟机(JVM)的运行时数据区域和JVM指令集,包括程序计数器、虚拟机栈、本地方法栈、直接内存、方法区和堆,以及栈帧的组成部分和执行流程。
31 2
JVM知识体系学习五:Java Runtime Data Area and JVM Instruction (java运行时数据区域和java指令(大约200多条,这里就将一些简单的指令和学习))
|
22天前
|
存储 算法 Java
Java虚拟机(JVM)的内存管理与性能优化
本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
|
1月前
|
存储 算法 Java
深入理解Java虚拟机(JVM)及其优化策略
【10月更文挑战第10天】深入理解Java虚拟机(JVM)及其优化策略
41 1
|
1月前
|
安全 Java API
🌟探索Java宇宙:深入理解Java技术体系与JVM的奥秘
本文深入探讨了Java技术体系的全貌,从Java语言的概述到其优点,再到Java技术体系的构成,以及JVM的角色。旨在帮助Java开发者全面了解Java生态,提升对Java技术的认知,从而在编程实践中更好地发挥Java的优势。关键词:Java, JVM, 技术体系, 编程语言, 跨平台, 内存管理。
35 2
|
1月前
|
小程序 Oracle Java
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
这篇文章是关于JVM基础知识的介绍,包括JVM的跨平台和跨语言特性、Class文件格式的详细解析,以及如何使用javap和jclasslib工具来分析Class文件。
41 0
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
|
1月前
|
监控 Java
Java的JVM如何优化?
Java的JVM如何优化?
55 3
|
2月前
|
存储 缓存 监控
【Java面试题汇总】JVM篇(2023版)
JVM内存模型、双亲委派模型、类加载机制、内存溢出、垃圾回收机制、内存泄漏、垃圾回收流程、垃圾回收器、G1、CMS、JVM调优
【Java面试题汇总】JVM篇(2023版)
|
2月前
|
安全 前端开发 Java
浅析JVM invokedynamic指令与Java Lambda语法的深度融合
在Java的演进历程中,Lambda表达式无疑是Java 8引入的一项革命性特性,它极大地简化了函数式编程在Java中的应用,使得代码更加简洁、易于阅读和维护。而这一切的背后,JVM的invokedynamic指令功不可没。本文将深入探讨invokedynamic指令的工作原理及其与Java Lambda语法的紧密联系,带您领略这一技术背后的奥秘。
28 1