深入学习JVM
文章平均质量分 96
hresh
这个作者很懒,什么都没留下…
展开
-
JVM系列之:你知道Java有多少种内存溢出吗
本文为《深入学习 JVM 系列》第二十五篇文章Java内存区域关于这部分内容大多来源于《深入理解Java虚拟机》一书。Java 运行时数据区域(JDK8)如下图所示:关于上述提到的线程共享和线程隔离区域,下图做详细讲解:程序计数器程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器来完。另外,在多线程的情况下,为了线程切换后能.原创 2022-04-06 23:44:42 · 1995 阅读 · 0 评论 -
JVM系列之:日志分析工具:GCViewer、VisualVM、GCeasy
本文为《深入学习 JVM 系列》第二十四篇文章GCViewerGCViewer 是一个可以将 JVM 中的 gc log 可视化的工具,使用该工具可以帮助你充分的发现 JVM 垃圾回收中的潜在问题,让你可以更加准确的做出关于 JVM GC 优化的决策。安装并启动git clone https://github.com/chewiebug/GCViewer.git//或者用 IDEA打开项目后,用 maven进行打包mvn clean pacakge//得到一个 jar包cd target.原创 2022-04-01 21:15:07 · 5530 阅读 · 0 评论 -
JVM系列之:MAT工具使用教程
本文为《深入学习 JVM 系列》第二十三篇文章Eclipse Memory Analyzer (MAT)是一个快速且功能丰富的Java堆分析器,可帮助您发现内存泄漏并减少内存消耗。安装并启动直接参考 Mac下MAT的安装需要注意的是注意 JDK 版本和 MAT 版本的映射,最新的 MAT 版本为 1.12.0,需要在 JDK11 以上运行。如果 JDK 版本为 11,且 MAT 版本是最新的,还需要修改 /Applications/mat.app/Contents/Eclipse/Memor.原创 2022-03-31 21:31:18 · 8368 阅读 · 0 评论 -
JVM系列之:GC调优基础以及初识jstat命令
本文为《深入学习 JVM 系列》第二十二篇文章影响垃圾收集性能有三个主要的属性,垃圾收集调优又有三个基本原则,以及垃圾收集调优时需要采集的信息。如果想要对垃圾收集进行调优,则需要根据实际场景对不同属性做出取舍,理解调优的原则以及收集什么信息。性能属性吞吐量吞吐量是评价垃圾收集器能力的重要指标之一,指不考虑垃圾收集引起的停顿时间或内存消耗,每单位时间可以执行的工作量的指标。通常,吞吐量的增加是以延迟增加和/或内存占用增加为代价的。一般吞吐量需求(Generic requirements for .原创 2022-03-30 22:32:38 · 923 阅读 · 0 评论 -
JVM系列之:你知道Jhsdb整合的故障处理工具
本文为《深入学习 JVM 系列》第二十一篇文章Jhsdb 是 JDK9 引入的新的命令行工具,它有 clhsdb、debugd、hsdb、jstack、jmap、jinfo、jsnap 这些 mode 可以使用,其中有几个在名称和功能上与以前的 JDK 发行版中可用的各个命令行工具相对应。看得出来,官方想要 jhsdb 工具整合多个其他工具的功能,甚至还做了一些功能拓展。所以本文将带大家认识一下 jhsdb 下的这些 mode。在使用 jhsdb 工具之前,必须先获取 PID,所以我们先来认识一下 .原创 2022-03-29 23:06:16 · 3425 阅读 · 0 评论 -
JVM系列之:关于即时编译器的其他一些优化手段
本文为《深入学习 JVM 系列》第二十篇文章在前面两篇文章讲述了即时编译器的两种特殊优化技术:方法内联和逃逸分析,其中基于逃逸分析结果又有三种优化方式:同步消除、栈上分配以及标量替换。除此之外,即时编译器还有很多优化手段,其中有不少经典编译器的优化手段,也有许多针对 Java 语言,或者说针对运行在 Java 虚拟机上的所有语言进行的优化。相较于方法内联,其他优化手段理解起来并不困难。一开始没打算整理这块内容,但是看了一下,觉得和之前的《如何提升代码质量》一文息息相关,除了要熟悉重构的手段,了解更深.原创 2022-03-28 20:47:39 · 687 阅读 · 0 评论 -
JVM系列之:关于逃逸分析的学习
本文为《深入学习 JVM 系列》第十九篇文章上文讲解完方法内联后,JIT 即时编译还有一个最前沿的优化技术:逃逸分析(Escape Analysis) 。废话少说,我们直接步入正题吧。逃逸分析首先我们需要知道,逃逸分析并不是直接的优化手段,而是通过动态分析对象的作用域,为其它优化手段提供依据的分析技术。具体而言就是:逃逸分析是“一种确定指针动态范围的静态分析,它可以分析在程序的哪些地方可以访问到指针”。Java虚拟机的即时编译器会对新建的对象进行逃逸分析,判断对象是否逃逸出线程或者方法。即时编译.原创 2022-03-27 20:41:53 · 6266 阅读 · 0 评论 -
JVM系列之:深入学习方法内联
在前面多篇文章中多次提到方法内联,作为编译器最重要的优化技术,该技术不仅可以消除调用本身带来的性能开销,还能够触发更多的优化。本文将带领大家对该技术一探究竟。方法内联方法内联指的是:在编译过程中遇到方法调用时,将目标方法的方法体纳入编译范围之中,并取代原方法调用的优化手段。以 getter/setter 为例,如果没有方法内联,在调用 getter/setter 时,程序需要保存当前方法的执行位置,创建并压入用于 getter/setter 的栈帧、访问字段、弹出栈帧,最后再恢复当前方法的执行。而当内原创 2022-03-24 22:25:09 · 1230 阅读 · 0 评论 -
JVM系列之:关于即时编译器的优化措施
本文为《深入学习 JVM 系列》第十七篇文章我们来继续讲解 Java 虚拟机中的即时编译。Profiling上篇文章中介绍了关于分层编译的交互关系图,这里再贴一遍。对于图片中描述的四种编译途径做过详细介绍,这里就不重复介绍了,其中提到了如下内容:分层编译中的 0 层、2 层和 3 层都会进行 profiling,收集能够反映程序执行状态的数据。其中,最为基础的便是 2层进行的 profiling,它只需要统计方法的调用次数以及循环回边的执行次数,当统计之和超过阈值就会触发即时编译。0 层和 .原创 2022-03-23 22:41:25 · 700 阅读 · 0 评论 -
JVM系列之:关于即时编译器的那些事
本文为《深入学习 JVM 系列》第十六篇文章我们在前文学习 Java 是如何执行的这篇文章中有提及即时编译器,这是一项用来提升应用程序运行效率的技术。通常而言,代码会先被 Java 虚拟机解释执行,之后反复执行的热点代码则会被即时编译成为机器码,直接运行在底层硬件之上。那么问题来了,既然在 HotSpot 中即时编译可以提升程序运行效率,为什么还需要解释器呢?解释器与编译器首先需要了解的是,并不是所有的 Java 虚拟机都采用解释器与编译器并存的运行架构, 但是主流的 Java 虚拟机,比如说 .原创 2022-03-22 22:05:13 · 1701 阅读 · 0 评论 -
JVM系列之:你知道Lombok是如何工作的吗
本文为《深入学习 JVM 系列》第十五篇文章在学习本文前,也许你只是用过 Lombok,知道有一些注解可以帮助我们快速开发,但是你是否了解它是怎么工作的,为什么可以产生这样的效果?让我们带着上述问题,开始本文的学习。在前文讲解《Javac编译器》时学习编译器的执行过程时,有这么一张流程图:第二步处理过程就是插入式注解处理器的注解处理过程,当时没做过多了解,本文就来好好学习一番。首先我们来认识一下注解。注解注解(Annontation)是 Java 5 引入的,Annontation 像一种.原创 2022-03-21 21:53:18 · 1759 阅读 · 0 评论 -
JVM系列之:初识Javac编译器和Java语法糖
本文为《深入学习 JVM 系列》第十四篇文章Javac编译器概念《Java虚拟机规范》 中严格定义了 Class 文件格式的各种细节, 可是对如何把 Java 源码编译为Class 文件却描述得相当宽松。这里的 javac 编译器称为前端编译器,其他的前端编译器还有诸如 Eclipse JDT 中的增量式编译器 ECJ 等。相对应的还有后端编译器,它在程序运行期间将字节码转变成机器码,如 HotSpot 自带的 JIT 编译器,后续章节我们会详细介绍。在《深入理解Java虚拟机》一文中描述了 j.原创 2022-03-20 21:05:57 · 1175 阅读 · 0 评论 -
JVM系列之:你知道为什么要有两个 Survivor吗?关于卡表技术又有多少了解
本文为《深入学习 JVM 系列》第十三篇文章分代收集理论以下内容来源于《深入理解Java虚拟机》一文。分代收集理论实质是一套符合大多数程序运行实际情况的经验法则, 它建立在两个分代假说之上:1、弱分代假说(Weak Generational Hypothesis) : 绝大多数对象都是朝生夕灭的。2、强分代假说(Strong Generational Hypothesis) : 熬过越多次垃圾收集过程的对象就越难以消亡基于上述两个分代假说,当前流行的垃圾收集器都遵循如下设计原则:收集器应该将.原创 2022-03-17 22:54:33 · 2115 阅读 · 0 评论 -
JVM系列之:聊一聊垃圾收集器
关于 JVM 垃圾回收内容比较多,本文将继续讲述一下 JVM 发展历程中的各个垃圾收集器,这部分内容大多来源于《深入理解Java虚拟机》一文,没有太多的扩展性内容可以补充,但是为了整个系列的完整性,还是补发一下。Serial 收集器Serial(串行)收集器收集器是最基本、历史最悠久的垃圾收集器,是基于标记-复制算法的新生代收集器。大家看名字就知道这个收集器是一个单线程收集器了。它的 “单线程” 的意义不仅仅意味着它只会使用一条垃圾收集线程去完成垃圾收集工作,更重要的是它在进行垃圾收集工作的时候必须暂停原创 2022-03-15 23:14:13 · 254 阅读 · 0 评论 -
JVM系列之:你真的了解垃圾回收吗
Java 虚拟机的自动内存管理,将原本需要由开发人员手动回收的内存,交给垃圾回收器来自动回收。因为是自动机制,我们平时不会直接接触,但还是有必要了解与垃圾回收实现相关的问题。下文先从基础开始学习垃圾回收。垃圾回收的目的垃圾回收的目的是回收堆内存中不再使用的对象所占的内存,释放资源。垃圾回收的时间回收时间:即触发 GC 的时间,在新生代的 Eden 区满了,会触发新生代 GC(Minor GC),经过多次触发新生代 GC 存活下来的对象就会升级到老年代,升级到老年代的对象所需的内存大于老年代剩余的内存原创 2022-03-14 21:56:42 · 1678 阅读 · 0 评论 -
JVM系列之:JVM是如何处理我们定义的对象生成代码
快要讲解 Java 垃圾回收机制了,在此之前我们有必要了解一下 Java 对象的内存分配和创建过程。JDK8内存区域Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。如下图所示:Java 对象分配内存主要与堆有关,所以此处只介绍一下堆内存。堆是 JVM 内存管理的最大的一块区域,此内存区域的唯一目的就是存放对象的实例,所有对象实例与数组都要在堆上分配内存。它也是垃圾收集器的主要管理区域。java 堆可以处于物理上不连续的空间,只要逻辑上是连续的即可。线程共享原创 2022-03-13 21:41:53 · 1412 阅读 · 0 评论 -
JVM系列之:JVM是怎么实现invokedynamic的?
invokedynamic 指令千呼万唤始出来,上一篇文章介绍了那么久的方法句柄,终于来到 invokedynamic 指令讲解了。invokedynamic 是 Java 7 引入的一条新指令,用以支持动态语言的方法调用。具体来说,它将调用点(CallSite)抽象成一个 Java 类,并且将原本由 Java 虚拟机控制的方法调用以及方法链接暴露给了应用程序。在运行过程中,每一条 invokedynamic 指令将捆绑一个调用点,并且会调用该调用点所链接的方法句柄。在第一次执行 invokedyna原创 2022-03-09 23:00:15 · 736 阅读 · 0 评论 -
JVM系列之:关于方法句柄的那些事
前言Java 字节码中与调用相关的指令共有五种。invokestatic:用于调用静态方法。invokespecial:用于调用私有实例方法、构造器,以及使用 super 关键字调用父类的实例方法或构造器,和所实现接口的默认方法。invokevirtual:用于调用非私有实例方法。invokeinterface:用于调用接口方法。invokedynamic:用于调用动态方法。invokestatic 和 invokespecial 是静态绑定的,invokevirtual 和 invoke原创 2022-03-08 23:48:50 · 1564 阅读 · 2 评论 -
JVM系列之:关于HSDB的一点心得
之前未接触过 HSDB 工具,在深入学习反射时,研究其源码时需要了解生成的字节码文件,恰巧看到别人使用了 HSDB 工具,因此花时间学习了一番。HSDB(Hotspot Debugger),是一款内置于 SA 中的 GUI 调试工具,可用于调试 JVM 运行时数据,从而进行故障排除。HSDB发展sa-jdi.jar在 Java9 之前,JAVA_HOME/lib 目录下有个 sa-jdi.jar,可以通过如下命令启动HSDB(图形界面)及CLHSDB(命令行)。java -cp /Library/原创 2022-03-07 21:22:01 · 1448 阅读 · 0 评论 -
JVM系列之:JVM是如何实现反射的
简介Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。在 Java 环境中运行时,对于任意一个类,能否知道这个类有哪些属性和方法。对于任意一个对象,能否调用它的任意一个方法。Java 反射机制主要提供了以下功能:在运行时判断任意一个对象所属的类。在运行时构造任意一个类的对象。在运行时判断任意一个类所具有的成员变量和方法。在运行时调用原创 2022-03-06 20:24:58 · 1091 阅读 · 0 评论 -
JVM系列之:聊一聊Java异常
异常的基本概念在 Java 语言规范中,所有异常都是 Throwable 类或者其子类的实例。Throwable 有两大直接子类。Throwable 是所有异常的根,java.lang.ThrowableError 是错误,java.lang.ErrorException 是异常,java.lang.ExceptionError类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。对于这类错误导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议原创 2022-03-02 21:58:39 · 201 阅读 · 0 评论 -
JVM系列之:JVM如何执行方法调用
深入理解重载和重写,在分析静态绑定和动态绑定的同时,对Java多态又有了新的认识,以及JVM如何识别方法并进行方法调用原创 2022-02-28 13:34:27 · 1059 阅读 · 0 评论 -
JVM系列之:关于JVM类加载的那些事
在上一篇文章中我们知道 Java 语言的类型可以分为两大类:基本类型(primitive types)和引用类型(reference types)。比如 Java 的基本类型,它们是由 Java 虚拟机预先定义好的。Java 引用类型主要分为四种:类、接口、数组类和泛型参数。由于泛型参数会在编译过程中被擦除,因此 Java 虚拟机实际上只有前三种。在类、接口和数组类中,数组类是由 Java 虚拟机直接生成的,其他两种则有对应的字节流。说到字节流,最常见的形式要属由 Java 编译器生成的 class 文原创 2022-02-19 11:45:38 · 497 阅读 · 0 评论 -
JVM系列之:聊聊Java的数据类型
在我刚接触 Java 学习时,第一个上手的程序就是关于 int 类型变量的计算,然后输出执行结果。后来慢慢地又接触到其他类型的变量,比如 long、double、char 等等,看起来都挺简单的。但是我们都听过 Java 是一门面向对象的开发语言,绝不可能仅限于这些基本的数据类型,于是又认识了 Integer、Double、Long 等数据类型,我们称之为基本数据类型的包装类。上述基本数据类型和对应的包装类(也称为引用类型),构成了 Java 虚拟机的数据类型。后续我们面对对象开发,构建的一个个类对象,都原创 2022-02-09 21:15:35 · 624 阅读 · 0 评论 -
JVM系列之:宏观分析Java代码是如何执行的
前言作为一名 Java 程序员,平日里都是和 Java 代码打交道,但是仅限于使用,比如说使用 Java 核心类库,以及调用第三方类库里的 API。凭借上述“本事”便可以专注于实现具体业务,并且依赖 Java 虚拟机自动执行乃至优化我们的应用程序。那么自己就仅限于此了吗?众所周知,JVM 和并发是应聘面试中两个绕不开的考点,大厂一些岗位招聘要求上明确写着熟悉甚至精通 JVM,掌握 JVM 性能调优技术。而我们在写简历时也需要慎用熟悉和精通这两个词,面试官会根据简历来发出不同深度的提问,JVM 知识考察如原创 2022-01-26 21:22:13 · 1347 阅读 · 0 评论