JVM快速入门篇

这篇具有很好参考价值的文章主要介绍了JVM快速入门篇。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、JVM探究

1.1前言

  1. 请你谈谈你对jvm的理解?
  2. Java8虚拟机和之前的变化更新?
  3. 什么是OOM?什么是栈溢出StackOverFlowError?怎么分析?
  4. jvm的常见调优参数有哪些?
  5. 内存快照如何抓取?怎么分析Dump文件?
  6. 谈谈jvm中,类加载器你的认识?

1.2内容分派

1. JVM的位置
2. JVM的体系结构
3. 类加载器
4. 双亲委派机制
5. 沙箱安全机制
6. Native
7. PC寄存器
8. 方法区
9. 栈
10. 三种JVM
11. 堆
12. 新生区、老年区
13. 永久区
14. 堆内存调优
15. GC

  1. 常用算法

16. JMM 

二、 JVM位置

JVM(Java Virtual Machine)是 Java 虚拟机,用于运行 Java 编译后的二进制字节码,最后生成机器指令。JVM 是 Java 能够跨平台的核心。JDK : (Java Development Kit),Java 开发工具包。JDK 是整个 Java 开发的核心,集成了 JRE 和javac.exe,java.exe,jar.exe 等工具。JRE : (Java Runtime Environment),Java 运行时环境。主要包含两个部分,JVM 的标准实现和 Java 的一些基本类库。它相对于 JVM 来说,多出来的是一部分的 Java 类库。

JVM 与操作系统之间的关系: JVM 上承开发语言,下接操作系统,它的中间接口就是字节码。

因此,JVM 的位置取决于你安装了哪个 JDK 版本和你的操作系统。如果你使用 Windows 操作系统,则可以在 cmd 中输入 java -version 命令来查看 JDK 的安装位置。如果你使用 Linux 操作系统,则可以在终端中输入 which java 命令来查看 JDK 的安装位置。

JVM快速入门篇,jvm

三、JVM体系结构

3.1 jvm结构图

JVM快速入门篇,jvm

3.2 jvm垃圾回收

垃圾回收,指的的堆内存的垃圾回收

在 JVM 中,有一个垃圾回收线程,它是低优先级的,在正常情况下是不会执行的,只有在虚拟机空闲或者当前堆内存不足时,才会触发执行,扫描那些没有被任何引用的对象,并将它们添加到要回收的集合中,进行回收

JVM 的垃圾回收机制主要是针对堆内存消亡的对象的回收和内存分配。在 JVM 进行垃圾回收之前,首先就是判断哪些对象是垃圾,也就是说,要判断哪些对象是可以被销毁的,其占有的空间是可以被回收的

Java 的垃圾回收机制主要采用了引用计数法和可达性分析算法两种方式来判断哪些对象可以被销毁。其中引用计数法是为每个对象创建一个引用计数,有对象引用时计数器 +1,引用被释放时计数 -1,当计数器为 0 时就可以被回收。但是它有一个缺点是不能解决循环引用的问题。可达性分析算法则从 GC Roots 开始向下搜索,搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时,则证明此对象是可以被回收的。

Java 的垃圾回收机制主要采用了四种垃圾回收算法:标记-清除算法、复制算法、标记-整理算法和分代算法。其中标记-清除算法效率不高,无法清除垃圾碎片;复制算法内存使用率不高;标记-整理算法效率较高;分代算法则根据对象存活周期的不同将内存划分为几块,一般包括年轻代、老年代和永久代。 JVM快速入门篇,jvm

3.3 jvm调优

JVM调优,99%是调堆

JVM 调优的目的是追求更低的系统延迟和更高的系统吞吐量,衡量系统在稳定状态下所需要的最低内存占用量。JVM 调优主要是针对垃圾收集器的收集性能优化,令运行在虚拟机上的应用能够使用更少的内存以及延迟获取更大的吞吐量

JVM 调优一般包含多个层次,比如:架构调优、代码调优、JVM 调优、数据库调优、操作系统调优等。其中架构调优和代码调优是 JVM 调优的基础,架构调优是对系统影响最大的

JVM 调优主要是通过不断测试调整 JVM 的运行参数,尽可能让对象都在新生代 (Eden) 里分配和回收,尽量别让太多对象频繁进入老年代,避免频繁对老年代进行垃圾回收,同时给系统充足的内存大小,避免新生代频繁的进行垃圾回收

JVM快速入门篇,jvm

四、类加载器

加载Class文件

4.1类加载的过程

JVM快速入门篇,jvm

4.2哪些类加载器

  1. 引导类加载器(BootstrapClassloader):用C++编写,是JVM自带的类加载器;负责加载Java的核心类库。(该加载器无法直接获取)
  2. 扩展类加载器(ExtClassloader):负责加载/jre/lib/ext目录下的jar包。
  3. 应用程序类加载器(AppClassloader):负责加载java -classpath或-D java.class.path所指的目录下的类与jar包。(最常用的加载器)

4.3双亲委派机制

  1. 类加载器接收到一个加载请求时,他会委派给他的父加载器,实际上是去他父加载器的缓存中去查找是否有该类,如果有就加载返回,如果没有则继续委派给父类加载,直到顶层类加载器。
  2. 如果顶层类加载器也没有加载该类,则会依次向下查找子加载器的加载路径,如果有就加载返回,如果都没有,则会抛出异常。
  3. 这种工作机制可以保证Java核心库的类型安全,防止用户自己编写的同名类被优先加载,从而确保Java程序的稳定运行

 五、 沙箱安全机制

Java沙箱安全机制是一种用于保护Java代码和本地系统之间的安全技术,它可以限制Java代码对本地资源的访问,防止其造成潜在的危害。Java沙箱安全机制的发展经历了几个阶段,从最初的完全隔离到后来的可配置的权限控制,以及引入了代码签名、域和安全管理器等概念。Java沙箱安全机制的基本组件包括字节码校验器、类加载器、存取控制器、安全管理器和安全软件包等

 六、native、方法区

6.1native

凡是使用了native关键字的,说明Java的作用范围已经达不到了,它会去调用底层的C语言的库。

  1. 进入本地方法栈。
  2. 调用本地方法接口。JNI

JNI的作用:扩展Java的使用,融合不同的语言为Java所用。(最初是为了融合C、C++语言)

因为Java诞生的时候,C和C++非常火,想要立足,就有必要调用C、C++的程序。

所以Java在JVM内存区域专门开辟了一块标记区域Native Method Area Stack,用来登记native方法。
在最终执行(执行引擎执行)的时候,通过JNI来加载本地方法库中的方法。

 6.2PC寄存器

程序计数器:Program Counter Register
每个线程都有一个程序计数器,是线程私有的,就是一个指针,指向方法区中的方法字节码(用来存储指向像一条指令的地址,也即将要执行的指令代码),在执行引擎读取下一条指令,是一个非常小的内存空间,几乎可以忽略不计。

6.3方法区

Method Area方法区(此区域属于共享区间,所有定义的方法的信息都保存在该区域)
方法区是被所有线程共享,所有字段、方法字节码、以及一些特殊方法(如构造函数,接口代码)也在此定义。

静态变量,常量、类信息(构造方法、接口定义)、运行时的常量池存在方法区中但是实例变量存在堆内存中,和方法区无关

static final, Class, 常量池

 七、栈(后进先出)

7.1栈的作用

栈内存,主管程序的运行,生命周期和线程同步;
线程结束,栈内存也就释放了,对于栈来说,不存在垃圾回收问题

7.2栈存储的东西

8大基本类型、对象引用,实例的方法。 

7.3 栈运行原理

7.3.1简单结构图

JVM快速入门篇,jvm

7.3.2详细结构图

JVM快速入门篇,jvm 7.3.3栈+堆+方法区的交互关系

JVM快速入门篇,jvm

八、堆

8.1三种JVM

  1. Sun公司的HotSpot。(java -version查看)
  2. BEA的JRockit
  3. IBM的J9VM

8.2. 堆

Heap,一个JVM只有一个堆内存,堆内存的大小是可以调节的。

类加载器读取了类文件后,一般会把什么东西放到堆中?
类、方法、常量、变量、保存我们所有引用类型的真实对象。

堆内存中细分为三个区域:

  • 新生区(伊甸园区)Young/New
  • 养老区 old
  • 永久区 Perm

JVM快速入门篇,jvm

8.3新生区

新生区又叫做伊甸园区,包括:伊甸园区、幸存0区、幸存1区。

8.4永久区

这个区域是常驻内存的。
用来存放JDK自身携带的Class对象、Interface元数据,存储的是Java运行时的一些环境或类信息~。
这个区域不存在垃圾回收
关闭JVM虚拟机就会释放这个区域的内存。

什么情况下,在永久区就崩了?

  • 一个启动类,加载了大量的第三方jar包。
  • Tomcat部署了太多的应用。
  • 大量动态生成的反射类;不断的被加载,直到内存满,就会出现OOM

8.5永久代和元空间 

这个区域常驻内存的。用来存放JDK自身携带的Class对象。Interface元数据 ,存储的是ava运行时的一些环境或类信息

什么是永久代和元空间??
方法区是一种规范,不同的虚拟机厂商可以基于规范做出不同的实现,永久代和元空间就是出于不同jdk版本的实现。
方法区就像是一个接口,永久代与元空间分别是两个不同的实现类。
只不过永久代是这个接口最初的实现类,后来这个接口一直进行变更,直到最后彻底废弃这个实现类,由新实现类—元空间进行替代。

jdk1.8之前:

JVM快速入门篇,jvm

jdk1.8以及之后:在堆内存中,逻辑上存在,物理上不存在(元空间使用的是本地内存)JVM快速入门篇,jvm 

九、使用JProfiler工具分析OOM原因

Java OOM异常通常是由于内存泄漏或者内存溢出导致的。内存泄漏指的是程序中已经不再使用的对象仍然被引用,导致垃圾回收器无法回收,最终导致内存溢出。而内存溢出则是指程序在申请内存时,没有足够的空间供其使用,最终导致程序崩溃

Java OOM异常通常有以下几种原因:

  • Java堆用于存储对象实例,只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么在对象数量到达最大堆的容量限制后就会产生内存溢出异常。
  • 无法在Java堆中分配对象。
  • 应用程序保存了无法被GC回收的对象。
  • 应用程序过度使用finalizer。

JVM快速入门篇,jvm

十、GC垃圾回收

 10.1垃圾回收的区域

JVM快速入门篇,jvm

10.2GC之引用计数法

10.3GC之复制算法

JVM快速入门篇,jvm

JVM快速入门篇,jvm

 好处:没有内存的碎片。

坏处:浪费了内存空间(多了一半空间to永远是空)。假设对象100%存活(极端情况),不适合使用复制算法。

使用场景

复制算法最佳使用场景:对象存活度较低的时候(新生区)

10.4 GC之标记清除压缩算法

10.4.1 标记清除

JVM快速入门篇,jvm

  • 优点:不需要额外的空间。
  • 缺点:两次扫描,严重浪费时间,会产生内存碎片。

10.4.2标记清除压缩

JVM快速入门篇,jvm

 标记清除压缩(改进)

 标记清除压缩(改进)

10.4.3 标记清除压缩(改进)

内存效率:复制算法>标记清除算法>标记压缩算法(时间复杂度)
内存整齐度:复制算法=标记压缩算法>标记清除算法
内存利用率:标记压缩算法=标记清除算法>复制算法

思考一个问题:难道没有最优算法吗?
答案:没有,没有最好的算法,只有最合适的算法——》GC:分代收集算法

年轻代:

  • 存活率低
  • 复制算法

老年代:

  • 区域大:存活率高
  • 标记清除(内存碎片不是太多)+标记压缩混合实现

十一、JMM是什么

11.1JMM是什么

JMM(Java Memory Model),Java的内存模型。

11.2 JMM的作用

缓存一致性的协议,用来定义数据读写的规则。

JMM定义了线程工作内存和主内存的抽象关系:线程的共享变量存储在主内存中,每个线程都有一个私有的本地工作内存。

使用volatile关键字来解决共享变量的可见性的问题。

Java内存模型是围绕着并发编程中原子性、可见性、有序性这三个特征来建立的。

11.3JMM的操作

JVM快速入门篇,jvm

JMM定义了8种操作来完成(每一种操作都是原子的、不可再拆分的)。

  • lock(锁定):作用于主内存的变量,它把一个变量标识为一条线程独占的状态。
  • unlock(解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定。
  • read(读取):作用于主内存的变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用。
  • load(载入):作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中。
  • use(使用):作用于工作内存的变量,它把工作内存中一个变量的值传递给执行引擎(每当虚拟机遇到一个需要使用到该变量的值的字节码指令时将会执行这个操作)。
  • assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量(每当虚拟机遇到一个给该变量赋值的字节码指令时执行这个操作)。
  • store(存储):作用于工作内存的变量,它把工作内存中一个变量的值传送到主内存中,以便随后的write操作使用。
  • write(写入):作用于主内存的变量,它把store操作从工作内存中得到的变量的值放入主内存的变量中。

11.4并发编程的三大特性

1. 原子性

一个或多个程序指令,要么全部正确执行完毕不能被打断,或者全部不执行

2. 可见性

当一个线程修改了某个共享变量的值,其它线程应当能够立即看到修改后的值。

3. 有序性

程序执行代码指令的顺序应当保证按照程序指定的顺序执行,即便是编译优化,也应当保证程序源语一致。文章来源地址https://www.toymoban.com/news/detail-703023.html

到了这里,关于JVM快速入门篇的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 用Arthas快速定位线上JVM问题!

           对于FullGC那一定不会陌生,一般来说会采用横切FullGC前置拦截(-XX:+HeapDumpBeforeFullGC)和后置拦截(-XX:+HeapDumpAfterFullGC),导出FullGC发生前后的heap dump文件,以便于我们进行FullGC原因的分析和定位。        我们如果希望可以观测到相关的GC回收次数以及相关的时间,

    2024年02月16日
    浏览(40)
  • JVM:从零到入门

    JVM,就是Java虚拟机。 JVM是一个巨大的话题,我们本文主要简单介绍一些围绕JVM相关的基础知识。 目录 JVM内存区域划分 本地方法栈 虚拟机栈 堆 程序计数器 方法区/ 元数据区 类加载 1.加载 2.验证 3.准备 4.解析 5.初始化 双亲委派模型 垃圾回收机制 引用计数 可达性分析 如何

    2024年01月17日
    浏览(42)
  • JVM入门(1)

    目录 虚拟机? JVM作用 JVM整体组成部分 一.类加载器 类加载过程 类什么时候会被加载(初始化)?    类加载器分类 1.引导类加载器 2.扩展类加载器 3.应用程序类加载器 4.自定义类加载器 双亲委派机制 打破双亲委派机制 二.运行时数据区     ①程序计数器     ②本地方法栈  

    2024年02月15日
    浏览(30)
  • jvm从入门到精通

    jvm 1.jvm与java体系结构 2.类加载子系统 3.运行时数据区概述及线程 4.程序计数器  5.虚拟机栈 6.本地方法接口 7.本地方法栈 8.堆                            

    2024年02月12日
    浏览(37)
  • JVM入门到精通

    Java Virtual Machine:Java虚拟机,用来保证Java语言跨平台 Java虚拟机可以看做是一台抽象的计算机,如同真实的计算机那样,它有自己的指令集以及各种运行时内存区域 Java虚拟机与Java语言并没有必然的联系,它只与特定的二进制文件格式(class文件格式所关联) Java 虚拟机就是一个

    2024年02月14日
    浏览(36)
  • 学习JVM---入门

    运行结果: native 是Java的一个,使用它可以调用本地方法,访问本地资源。 Thread类中的一个用法: private native void start0(); 执行到start0()时,start0()进入本地方法栈,然后调用本地方法接口JNI(Java Native Interface),然后调用本地方法库。 存哪些东西 static变量 final变量 Cl

    2024年02月08日
    浏览(36)
  • 【JVM从入门到实战】(六)类加载器的双亲委派机制

    在Java中如何使用代码的方式去主动加载一个类呢? 方式1:使用Class.forName方法,使用当前类的类加载器去加载指定的类。 方式2:获取到类加载器,通过类加载器的loadClass方法指定某个类加载器加载。 双亲委派机制: 自底向上查找是否加载过,再由顶向下进行加载 面试题:

    2024年02月04日
    浏览(49)
  • 【JVM】JVM执行流程 && JVM类加载 && 垃圾回收机制等

    目录 🌷1、JVM是什么? 🌷2、JVM的执行流程(能够描述数据区5部分) 🌷3、JVM类加载过程 🌷4、双亲委派机制:描述类加载的过程 问题1:类加载器 问题2:什么是双亲委派模型?  问题3:双亲委派模型的优点 🌷5、垃圾回收机制(重要,针对的是堆)    问题1:判定对象

    2024年02月15日
    浏览(59)
  • 【JVM】JVM常用指令

    性能诊断是软件工程师在日常工作中需要经常面对和解决的问题,在用户体验至上的今天,解决好应用的性能问题能带来非常大的收益。Java 作为最流行的编程语言之一,其应用性能诊断一直受到业界广泛关注。可能造成 Java 应用出现性能问题的因素非常多,例如线程控制、

    2024年02月08日
    浏览(38)
  • JVM——JVM参数指南

    在本篇文章中,你将掌握最常用的 JVM 参数配置。如果对于下面提到了一些概念比如堆、 Java 虚拟机所管理的内存中最大的一块,Java 堆是所有线程共享的一块内存区域,在虚拟机启动时创建。 此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里

    2024年02月12日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包