Java虚拟机
文章平均质量分 90
JVM、JMM
A minor
本来无一物,何处惹尘埃
展开
-
【JVM】类加载器(三):常见问题分析
前面文章讲过,在不指定父类加载器的情况下,默认采用系统类加载器。可能有人觉得不明白,现在我们来看一下JDK对应的代码实现。// 摘自java.lang.ClassLoader.java protected ClassLoader() {= null) {//... }//... }//... }//... }//... }//本机对应输出如下:所以,我们现在可以相信当自定义类加载器没有指定父类加载器的情况下,默认的父类加载器即为系统类加载器。原创 2023-03-12 00:52:43 · 209 阅读 · 0 评论 -
【JVM】类加载器(一):类加载机制及自定义ClassLoader
入口,定义了 加载/寻找 Class 的策略。比如双亲委派,或者其他形式调用 findClass() 读入 class 文件,并生成 Class 对象根据 class 名,在当前 ClassLoader 能处理路径中查找,如果能找到就将 class 文件读入调用 defineClass 生成 Class 对象native 方法将字节数组生成 Class 对象。原创 2023-03-12 00:28:26 · 1219 阅读 · 0 评论 -
【JVM】类加载器(二):Tomcat 打破双亲委派
首先思考一个问题,整个Tomcat容器是一个Java进程,假若Tomcat中同时部署了两个应用,应用A依赖Spring3.0,应用B依赖Spring5.0,那么Tomcat如何决定使用哪个版本的依赖呢。所以,按照JDK自带的双亲委派模型是无法解决的,因为ClassLoader#loaderClass默认会检查这个类有没有加载过,保证了类在进程中是唯一的。如果我们想加载两个版本的类,需要打破原有的模型。原创 2023-03-12 00:29:47 · 1715 阅读 · 0 评论 -
【JVM】基础内容(一):class 字节码文件结构详解
Java之所以可以“一次编译,到处运行”,一是因为JVM针对各种操作系统、平台都进行了定制(JRE),二是因为无论在什么平台,都可以编译生成固定格式的字节码(.class文件)供JVM使用。因此,也可以看出字节码对于Java生态的重要性。那到底什么是字节码?之所以被称之为字节码,是因为字节码文件由十六进制值组成,而JVM以两个十六进制值为一组,即以字节为单位进行读取(1个十六进制位=4个二进制位)。除此之外,由于JVM规范的存在,只要最终可以生成符合规范的字节码就可以在JVM上运行,因此这就给了各种运行在原创 2020-10-21 21:11:58 · 1556 阅读 · 0 评论 -
【JVM】基础内容(二):指令助记符总结及基本指令大全
在看具体指令前,先对所有指令做个总结:变量到操作数栈:iload,iload_,lload,lload_,fload,fload_,dload,dload_,aload,aload_操作数栈到变量:istore,istore_,lstore,lstore_,fstore,fstore_,dstore,dstor_,astore,astore_常数到操作数栈:bipush,sipush,ldc,ldc_w,ldc2_w,aconst_null,iconst_ml,iconst_,lconst原创 2020-10-21 14:35:25 · 1800 阅读 · 0 评论 -
【JVM】整体结构(一):类加载子系统
Java 虚拟机(java virtual machine,JVM),一种能够运行 Java 自己 Emma 的虚拟机。作为一种编程语言的虚拟机,实际上不只是专用于 Java 语言,只要生成的编译文件匹配JVM对加载编译文件的格式要求,任何语言都可以由 JVM 编译运行。比如 kotlin、scala等。JVM有很多,不只是Hotspot,还有Jrockit、J9等等。JVM主要由三个主要的子系统构成:类加载子系统,运行时数据区(内存结构),执行引擎。本篇我们先来看类加载子系统。Java 之所以可原创 2021-02-19 00:55:39 · 245 阅读 · 0 评论 -
【JVM】整体结构(二):运行时数据区
Java虚拟机(java virtual machine,JVM),一种能够运行Java自己Emma的虚拟机。作为一种编程语言的虚拟机,实际上不只是专用于Java语言,只要生成的编译文件匹配JVM对加载编译文件的格式要求,任何语言都可以由JVM编译运行。比如 kotlin、scala等。JVM有很多,不只是Hotspot,还有Jrockit、J9等等。JVM主要由三个主要的子系统构成:类加载子系统,运行时数据区(内存结构),执行引擎。1.类加载子系统Java之所以可以“一次编译,到处运行”,一是因原创 2020-10-21 22:27:50 · 2000 阅读 · 0 评论 -
【JVM】整体结构(三):执行引擎
在前面两篇文章,我们介绍了类加载子系统和运行时数据区【JVM】整体结构(一):类加载子系统【JVM】整体结构(二):运行时数据区本篇我们就来看看 JVM 的最后一个部分,执行引擎。JVM 的主要任务是负责装载字节码到其内部,但字节码并不能够直接运行在操作系统之上,因为字节码指令并非等价于本地机器指令,它内部包含的仅仅只是一些能够被JVM锁识别的字节码指令、符号表和其他辅助信息。那么,如果想让一个Java程序运行起来,这就涉及到了JVM的字节码执行引擎。执行引擎其实就是个运算器,能识别输入的指原创 2021-02-19 02:01:33 · 479 阅读 · 0 评论 -
【JVM】Java 中的三种常量池
原文链接:https://tangxman.github.io/2015/07/27/the-difference-of-java-string-pool/,本文做了一些简单排版在java的内存分配中,经常听到很多关于常量池的描述,我开始看的时候也是看的很模糊,网上五花八门的说法简直太多了,最后查阅各种资料,终于算是差不多理清了,很多网上说法都有问题,笔者尝试着来区分一下这几个概念。1.全局字符串池(string pool也有叫做string literal pool)全局字符串池里的内容是在类加.转载 2021-02-20 00:40:48 · 978 阅读 · 0 评论 -
【JVM】底层实现(一):浅谈 OOP-Klass 对象模型
当我们在写 Java 代码的时候,我们会面对着无数个接口,类,对象和方法。但我们有木有想过,Java 中的这些对象、类和方法,在 HotSpot JVM 中的结构又是怎么样呢?HotSpot JVM 底层都是 C++ 实现的,那么 Java 的对象模型与 C++ 对象模型之间又有什么关系呢?今天就来分析一下 HotSpot JVM 中的对象模型:oop-klass model。1.OOP-Klass 模型概述HotSpot JVM 并没有根据 Java 实例对象直接通过虚拟机映射到新建的 C++ 对象,原创 2020-10-22 21:52:26 · 2591 阅读 · 5 评论 -
【JVM】底层实现(二):创建一个对象的过程(转)
原文链接:https://zhuanlan.zhihu.com/p/48165015,本文做了简单排版。定义两个简单的类AAA和BBB通过javap -c AAA查看编译之后的字节码,具体如下:new 指令的实现过程Java 中的 new 关键字对应 jvm 中的 new 指令,定义在 InterpreterRuntime 类中PS:其中 pool是 AAA 的 constant pool,此时 AAA 的 class 已经加载到虚拟机中,new 指令后面的#2表示BBB类全限定名的.转载 2021-02-19 16:15:57 · 270 阅读 · 0 评论 -
【JVM】底层实现(三):对象初始化流程 --init 方法、cinit 方法
Java 的两种类内变量初始化方式:成员变量:在实例构造器<init>方法中进行,比如 int x = 1类变量:在类构造器 <cinit> 方法中或者使用 class ConstantValue 属性,static int x = 1:这里再多说一句,对于 static 变量的初始化,目前 Sun Javac 编译器的选择是:如果同时使用 final 和 static 来修饰一个变量,并且这个变量的数据类型是基本类型或者 java.lang.String 的话,就生成原创 2021-02-18 22:36:42 · 2317 阅读 · 1 评论 -
【JVM】底层实现(四):Object#hashCode 返回的是对象内存地址?(转)
原文链接:https://www.jianshu.com/p/be943b4958f4基于OpenJDK 8一直以为 Java Object.hashCode() 的结果就是通过对象的内存地址做相关运算得到的,但是无意在网上看到有相应的意见争论,故抽时间从源码层面验证了剖析了 hashCode 的默认计算方法。先说结论:OpenJDK8 默认hashCode的计算方法是通过和当前线程有关的一个随机数+三个确定值,运用Marsaglia’s xorshift scheme随机数算法得到的一个随机.转载 2021-03-15 18:52:22 · 375 阅读 · 0 评论 -
【JVM】堆(Heap)上有什么?普通对象全方位解析
1.对象存储布局一个Java对象在内存中包括3个部分:对象头、实例数据和对齐填充1.1 对象头Mark Word状态标识。与虚拟机位数一样,一般64bit,32bit很少。下图是一个32位虚拟机的Mark Word示例:从对象头中可以获取到两点信息:Minor GC年龄默认15,是因为分代年龄只有4bit,最大就是15有锁状态无HashCode是因为没空间存了Klass Pointer指针,指向相应类信息的地址(方法区)。大小也是由虚拟机位数决定,但 64bit 时由于 Klass原创 2020-10-22 00:29:54 · 2055 阅读 · 0 评论 -
【JVM】堆(Heap)上有什么?Class对象到反射
反射是什么?Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法可以简单理解为,在运行状态控制台输入一个(全)类名就可以得到一个该类对象,或者获取到该类的信息可以实现类的动态加载对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。而这也是Java被视为动态或准动态语言的一个关键性质。(为啥要说是准动态,因为一般而言的动态语言定义是程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。从这个观点看,Perl,Python,Ruby是动态语言,原创 2020-10-22 19:51:57 · 1446 阅读 · 0 评论 -
【JVM】GC(一):垃圾回收判断
GC是由JVM自动完成的,根据JVM系统环境而定,所以时机是不确定的。 当然,我们可以手动进行垃圾回收, 比如调用System.gc()方法通知JVM进行一次垃圾回收,但是具体什么时刻运行也无法控制。也就是说 System.gc()只是通知要回收,什么时候回收由JVM决定。 但是不建议手动调用该方法,因为消耗的资源比较大。一般以下几种情况会发生垃圾回收:(1)当Eden区或者S区不够用了 (2)老年代空间不够用了 (3)方法区空间不够用了 (4)System.gc()1.对象回收堆中几乎放着所有的对象原创 2021-02-19 17:30:20 · 792 阅读 · 0 评论 -
【JVM】GC(二):垃圾回收算法
在上一篇文章,我们介绍了什么时候情况下就可以回收垃圾了,但是回收的时候应该怎么做呢?基本的垃圾回收算法有以下四种:1.标记-清除算法它是最基础的收集算法,这个算法分为两个阶段,“标记”和”清除“。首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。它有两个不足的地方:效率问题,标记和清除两个过程的效率都不高;空间问题,标记清除后会产生大量不连续的碎片;2.标记整理根据老年代的特点提出的一种标记算法,标记过程和“标记-清除”算法一样,但是后续步骤不是直接对可回收对象进行回收原创 2021-02-19 17:06:29 · 232 阅读 · 0 评论 -
【JVM】GC(三):垃圾收集器
1.回收判断1.1 如何判断一个对象可以被回收堆中几乎放着所有的对象实例,对堆垃圾回收前的第一步就是要判断哪些对象已经死亡(即不能再被任何途径使用的对象)1.1.1 引用计数法给对象添加一个引用计数器,每当有一个地方引用,计数器就加1。当引用失效,计数器就减1。任何时候计数器为0的对象就是不可能再被使用的。这个方法实现简单,效率高,但是目前主流的虚拟机中没有选择这个算法来管理内存,最主要的原因是它很难解决对象之前相互循环引用的问题。所谓对象之间的相互引用问题,通过下面代码所示:除了对象a和b相互引原创 2020-10-22 22:34:20 · 4430 阅读 · 0 评论 -
【JVM】GC(四):GC日志格式解析
后面会结合实例来说明,先准备一个jar包,这里我拿的是一个启动 eureka 的 SpringBoot 项目。启动成功后在浏览器验证能够正常访问:那下面我们就分别配置不同的垃圾收集器,然后分析它们的日志内容。PS:打印GC日志的JVM参数是:-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:./gc.log -jar1.Parallel Scavenge收集器(默认)因为 Parallel原创 2021-02-19 18:07:39 · 687 阅读 · 0 评论 -
【JVM】关于GC必须知道的几个问题
1.内存泄漏与内存溢出的区别?内存泄漏:对象无法得到及时的回收,持续占用内存空间,从而造成内存空间的浪费。内存溢出:内存泄漏到一定的程度就会导致内存溢出,但是内存溢出也有可能是大对象导致的。2.young gc会有stw吗?不管什么 GC,都会有 stop-the-world,只是发生时间的长短。3.major gc和full gc的区别?major gc指的是老年代的gc,而full gc等于young+old+metaspace的gc。4.G1与CMS的区别是什么?CMS 用于老年原创 2020-10-24 04:45:51 · 2754 阅读 · 0 评论 -
【JVM】监控调优(一):JVM常用参数
1.JVM参数1.1 标准参数-version-help-server-cp1.2 -X参数非标准参数,也就是在JDK各个版本中可能会变动-Xint 解释执行-Xcomp 第一次使用就编译成本地代码-Xmixed 混合模式,JVM自己来决定1.3 -XX参数(最常使用)使用的最多的参数。非标准化参数,相对不稳定,主要用于JVM调优和Debuga.Boolean类型 格式:-XX:[+-]<name> +或-表示启用或者禁用原创 2020-10-23 17:08:32 · 1511 阅读 · 0 评论 -
【JVM】监控调优(二):JVM基本命令
在上一篇文章我们介绍了 JVM 常用参数,下面我们就来看看有哪些基本命令。1.jps查看java进程。结果为进程ID和进程名2.jinfo查看环境信息,实时查看和调整JVM配置参数1)查看 java 系统属性等同于System.getProperties()。格式:jinfo -sysprops 218802)查看JVM参数格式:jinfo -flag name PID (查看某个进程的name属性的值)jinfo -flag MaxHeapSize PID #原创 2021-02-19 17:48:13 · 170 阅读 · 0 评论 -
【JVM】监控调优(三):可视化工具
通过前两篇的介绍,参数也了解了,命令也知道了,关键是用起来不是很方便,要是有图形化的界面就好了。【JVM】调优相关(一):JVM常用参数【JVM】调优相关(二):JVM基本命令1.jconsoleJConsole工具是JDK自带的可视化监控工具。查看java应用程序的运行概况、监控堆信息、永久代使用情况、类加载情况等。启动方式:命令行输入 jconsole2.jvisualvm1)监控本地Java进程:可以监控本地的java进程的CPU,类,线程等2)监控远端Java进程:比如监原创 2021-02-19 17:51:56 · 332 阅读 · 0 评论 -
【JVM】监控调优(四):GC调优实操(gceasy)
JVM调优主要就是调整下面两个指标停顿时间:垃圾收集器做垃圾回收中断应用执行的时间。-XX:MaxGCPauseMillis吞吐量:运行用户代码时间/(运行用户代码时间+垃圾收集时间)。-XX:GCTimeRatio=n停顿时间越短就越适合需要和用户交互的程序,良好的响应速度能提升用户体验; 高吞吐量则可以高效地利用CPU时间,尽快完成程序的运算任务,主要适合在后台运算而不需要太多交互的任 务。1.GC调优步骤打印GC日志(注:Tomcat可以直接加载JAVA_OPTS变量里)-原创 2020-10-24 04:36:32 · 40843 阅读 · 3 评论 -
【JVM】JMM(一):与硬件架构关系?与JVM关系?
1.硬件架构假如是要设计Java虚拟机,那么最先要分析的一定是计算机硬件情况。由于CPU速度快,所以在内存之前会有一个CPU缓存,所以这时就会存在内存与CPU缓存一致性的问题。解决方案一:总线加锁(BUS),但是会降低CPU吞吐量解决方案二:MESI协议。比如,当CPU在CACHE中操作数据时,如果该数据是共享变量,数据在CACHE读到寄存器中,进行新修改,并更新内存数据,CACHE LINE置为无效,其他的CPU在内存中读取数据。2.JMMJMM只是一个模型,可以看做是对硬件架构的抽象:原创 2020-10-25 18:54:31 · 1682 阅读 · 1 评论 -
【JVM】JMM(二):JMM 的必要性?
JMM 系列:【JVM】JMM(一):与硬件架构关系?与JVM关系?【JVM】JMM(二):JMM 的必要性?【JVM】JMM(三):JMM 如何保证并发时的一致性问题?假设主内存中存在一个共享变量x,现在有A和B两条线程分别对该变量x=1进行操作, A/B线程各自的工作内存中存在共享变量副本x。假设现在A线程想要修改x的值为2,而B线程却想要读取x的值,那么B线程读取到的值是A线程更新后的值2还是更新前的值1呢?答案是, 不确定,即B线程有可能读取到A线程更新前的值1,也有可能读取到A线.原创 2021-04-13 22:50:11 · 201 阅读 · 0 评论 -
【JVM】JMM(三):JMM 如何保证并发时的一致性问题?
JMM 系列:【JVM】JMM(一):与硬件架构关系?与JVM关系?【JVM】JMM(二):JMM 的必要性?【JVM】JMM(三):JMM 如何保证并发时的一致性问题?Java 内存模型就是为了解决多线程环境下共享变量的一致性问题,那么一致性包含哪些内容呢?一致性主要包含三大特性:原子性、可见性、有序性,下面我们就来看看Java内存模型是怎么实现这三大特性的。1.原子性原子性指的是一个操作是不可中断的,即使是在多线程环境下,一个操作一旦开始就不会被其他线程影响。X=10; //.原创 2021-04-13 22:50:27 · 389 阅读 · 0 评论