Java虚拟机
Java虚拟机相关文章
一个长不胖的程序YUAN
来自贵州遵义,儿时留守形成一种独立思考、做事严谨、不怕吃苦的性格。喜欢与人交流分享知识,喜欢研究技术与阅读优秀作品。学习,这条路总是孤独并充满喜悦的。社会中有很多机遇,是否成功在于你如何把握。当然在机遇中也会遇到朋友,你必须学会信任,吸收每一份掌声,坚信每一点实力,展现自己的未来。愿你我越来越幸福...
展开
-
你会导出GC日志 知道怎样使用工具分析日志吗?【入门篇】
考虑到有的小伙伴还不怎么会在IDEA中去设置一些GC相关的参数和不怎么会读日志信息,所以我就又写了一篇关于参数和怎么读GC日志的文章,地址:https://blog.csdn.net/qq_43012792/article/details/108006349使用工具查看日志1、首先说一下有什么工具可以分析GC日志呢?常用的日志分析工具有: GCeasy(推荐)、GCViewer(软件)、GCHisto、GCLogViewerHpjmeter、garbagecat等。2、GCeasy:这个工具是免费.原创 2020-08-14 15:53:39 · 5006 阅读 · 0 评论 -
Java对象头的内部结构(new Object这个对象里面到底有什么)及锁状态信息【图文】
1、创建了Customer()实例 和 Account()实例2、对象头里包括:运行时元数据、类型指针、实例数据、对齐填充① 运行时元数据里又包括:哈希值(HashCode)、GC分代年龄、锁状态标志哈希值:它是一个地址,用于栈对堆空间中对象的引用指向,不然栈是无法找到堆中对象的GC分代年龄:记录幸存者区对象被GC之后的年龄age,,一般age为15之后下一次GC就会直接进入老年代锁状态标志:记录一些加锁的信息② 类型指针:是对方法区中类元信息的引用③ 实例数据:真实记录一个对象包含的数据.原创 2020-07-22 10:51:22 · 5634 阅读 · 2 评论 -
new String(“ab“)到底创建了几个对象?new String(“a“) + new String(“b“)呢?
1、执行 String str = new String(“ab”);后生成的字节码结论:单纯执行new String(“XXX”),底层会创建两个对象。一个是在堆中创建XXX的对象,另一个是在堆中字符串常量池中创建。这两个对象的内容都是一样的,但是地址是不相同的。2、升级:执行 String str = new String(“a”) + new String(“b”);后生成的字节码总结:另外:我还写了一篇String的文章,内容还多的,可以看看。里面有一道超级经典的intern面试题.原创 2020-07-18 15:59:43 · 8184 阅读 · 3 评论 -
几张清晰的图讲清楚什么是Java堆碎片?(内存碎片化)
单纯的分享,什么是Java堆碎片?这篇文章没有深入的讲解垃圾回收算法和垃圾回收器有兴趣了解垃圾回收篇的知识的话,可以看我另一篇三万字的文章哦!1、Java堆碎片是一个有趣的问题,它会导致长时间暂停完整的垃圾收集周期。在本文中,我们想尝试解释堆碎片。假设开发人员编写了一个代码“new BMW ()”。 这将在堆内存空间中创建一个新的BMW对象。例:2、假设现在应用程序再创建3个新对象:“丰田”, “本田”, “特斯拉”。 现在,JVM的堆内存将开始如下所示:3、假设一段时间后,没有其他对象引用T.原创 2020-07-21 23:36:44 · 5456 阅读 · 4 评论 -
带你读懂Java GC日志信息 教你如何使用工具查看【图文演示】
1、通过阅读GC日志,我们可以了解Java虛拟机内存分配与回收策略。内存分配与垃圾回收的参数列表:(1)-XX:+PrintGC 输出GC日志(这个只会显示总的GC堆的变化)。类似: -verbose:gc(2)-XX:+PrintGCDetails 输出GC的详细日志(我最常用)(3)-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)(4)-XX:+PrintGCDateStamp 输出GC的时间戳(以日期的形式,如2013-05-04T21:53:59.23.原创 2020-08-14 15:56:09 · 15677 阅读 · 0 评论 -
Garbage First (G1) GC垃圾回收器:区域化分代式【图文】
1、问:既然我们已经有了前面几个强大的GC,为什么还要发布Garbage First (G1) GC?答:(1)原因就在于应用程序所应对的业务越来越庞大、复杂,用户越来越多,没有GC就不能保证应用程序正常进行,而经常造成STW的GC又跟不上实际的需求,所以才会不断地尝试对GC进行优化。G1 (Garbage-First)垃圾回收器是在Java7 update 4之后引入的一个新的垃圾回收器,是当今收集器技术发展的最前沿成果之一(最新的是ZGC)。(2)与此同时,为了适应现在不断扩大的内存和不断增加的处.原创 2020-07-21 19:54:24 · 4119 阅读 · 0 评论 -
减少系统的停顿时间(STW)的增量收集算法 和分区算法
减少系统的停顿时间有两种算法:一种是增量收集算法,另一种是:分区算法增量收集算法1、上述现有的算法,在垃圾回收过程中,应用软件将处于一种stop the world的状态。在Stop the World状态下,应用程序所有的线程都会挂起,暂停一切正常的工作,等待垃圾回收的完成。如果垃圾回收时间过长,应用程序会被挂起很久,将严重影响用户体验或者系统的稳定性。为了解决这个问题,即对实时垃圾收集算法的研究直接导致了增量收集( Incremental Collecting) 算法的诞生。.2、基本思想如果.原创 2020-07-21 13:16:03 · 13646 阅读 · 0 评论 -
七大经典垃圾回收器篇+部分调优 不会让你失望(两万字)【图文】
文章目录一、垃圾回收器分类二、评估GC的性能指标三、吞吐量 VS 暂停时间四、垃圾回收器发展史五、七大经典的垃圾回收器一、垃圾回收器分类1、按垃圾回收线程数分,可以分为串行垃圾回收器和并行垃圾回收器。(1)串行回收指的是在同一时间段内只允许有一个CPU用于执行垃圾回收操作,此时工作线程被暂停,直至垃圾收集工作结束。➢在诸如单CPU处理器或者较小的应用内存等硬件平台不是特别优越的场合,串行回收器的性能表现可以超过并行回收器和并发回收器。所以,串行回收默认被应用在客户端的Client模式下的JVM中。6原创 2020-07-20 17:05:11 · 16056 阅读 · 2 评论 -
如何查看JDK不同版本默认使用的垃圾回收器(JDK 1.8 默认采用的是ParallelGC)【图文】
查看JDK不同版本使用的垃圾回收器,设置参数:-XX:+PrintCommandLineFlags(我截图中少了一个加号+)结论:JDK 1.8 默认采用的是ParallelGC ,JDK 1.9默认采用的就是 G1 垃圾回收器了。两外:推荐 --> 看完面试就够了-- JVM垃圾回收篇(Garbage Collection)两万字【图文并茂】我写的,哈哈哈,自我推荐了有用点个关注,手留余香!???? ???? ????...原创 2020-07-20 15:24:08 · 7594 阅读 · 3 评论 -
Java垃圾回收--强引用、软引用、弱引用、虚引用 详细
1、引出为什么要有这么多引用?我们希望能描述这样一类对象: 当内存空间还足够时,则能保留在内存中;如果内存空间在进行垃圾收集后还是很紧张,则可以抛弃这些对象。2、既偏门又非常高频的面试题 ,问题:强引用、软引用、弱引用、虚引用有什么区别?具体使用场景是什么?在JDK 1. 2版之后,Java对引用的概念进行了扩充将引用分为强引用(StrongReference)、软引用(Soft Reference) 、弱引用(Weak Reference) 和虚引用(Phantom Reference) 4种,这.原创 2020-07-19 23:14:04 · 4815 阅读 · 0 评论 -
Java程序执行过程中的 安全点、安全区域(内有JVM篇)
安全点(Safepoint)1、概念:程序执行时并非在所有地方都能停顿下来开始GC,只有在特定的位置才能停顿下来开始GC,这些位置称为“安全点(Safepoint)2、SafePoint的选择很重要,如果太少可能导致GC等待的时间太长(STW),如果太频繁可能导致运行时的性能问题。大部分指令的执行时间都非常短暂,通常会根据是否具有让程序长时间执行的特征为标准。比如:选择一些执行时间较长的指令作为SafePoint,如方法调用、循环跳转和异常跳转等。3、如何在GC发生时,检查所有线程都跑到最近的安全点停原创 2020-07-19 21:42:07 · 16852 阅读 · 7 评论 -
Java虚拟机中STW(stop the world)是什么意思
Stop-the-World,简称STW1、指的是GC事件发生过程中,会产生应用程序的停顿。停顿产生时整个应用程序线程都会被暂停,没有任何响应, 有点像卡死的感觉,这个停顿称为STW。(1)可达性分析算法中枚举根节点(GC Roots)会导致所有Java执行线程停顿。① 分析工作必须在一一个能确保一 致性的快照中进行② 一致性指整个分析期间整个执行系统看起来像被冻结在某个时间点上③ 如果出现分析过程中对象引用关系还在不断变化,则分析结果的准确性无法保证(2)被STW中断的应用程序线程会在完成GC原创 2020-07-19 21:12:45 · 12571 阅读 · 0 评论 -
System.gc()的理解 显式触发Full GC【代码证明】
System.gc()的理解1、在默认情况下,通过System. gc()或者Runtime . getRuntime() .gc()的调用,会显式触发Full GC,同时对老年代和新生代进行回收,尝试释放被丢弃对象占用的内存。2、然而System. gc()调用附带一个免责声明,无法保证对垃圾收集器的调用。也就是说调用System. gc() JVM不一定会去Full GC3、JVM实现者可以通过System. gc印)调用来决定JVM的GC行为。而- -般情况下,垃圾回收应该是自动进行的,无须手原创 2020-07-19 17:46:14 · 7152 阅读 · 1 评论 -
分代收集算法、减少系统的停顿时间( STW )的算法(增量收集、分区算法)
一、分代收集算法难道就没有-种最优算法吗?回答:无,没有最好的算法,只有最合适的算法。1、前面所有这些算法中,并没有一种算法可以完全替代其他算法,它们都具有自己独特的优势和特点。分代收集算法应运而生。2、分代收集算法,是基于这样一个事实:不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率。一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点使用不同的回收算法,以提高垃圾回收的效率。3、在Java程序运行的过程中,会产生大量的对象,其中有些原创 2020-07-19 17:22:58 · 4402 阅读 · 0 评论 -
垃圾清除阶段之标记 - 清除算法 复制算法 标记 - 压缩算法及算法的对比 【图文】
清除阶段(Sweep)一个对象出现第一次没有被引用的情况,就会被加入到F-Queue队列等待执行finalize()方法判断是否有机会复活或者直接被当作垃圾回收。以便有足够的可用内存空间为新对象分配空间。目前JVM有三种常见的垃圾回收算法:标记 - 清除算法(Mark - Sweep)、复制算法、标记压缩算法一、标记 - 清除算法(Mark - Sweep)1、背景:标记 - 清除算法(Mark - Sweep)是一种非常基础和常见的垃圾回收算法,该算法被J.MaCarthy等人再1960年提出并应原创 2020-07-19 17:20:00 · 14751 阅读 · 2 评论 -
垃圾标记阶段--引用计数算法、可达性分析算法
前言:对象存活判断在垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象。只有对死亡对象的标记才会被GC释放空间,因此这个过程可以称为垃圾标记阶段。简单来说,当一个对象已经不再被任何的存活对象继续引用时,就可以宣判为已经死亡。判断对象的存活一般有两种方式:引用计数算法 和 可达性分析算法。一、引用计数算法(Java未使用)1、原理:引用计数算法,对每个对象保存一个整型的引用计数器属性。用于记录对象被引用的情况。对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就原创 2020-07-19 17:15:28 · 13749 阅读 · 0 评论 -
看完面试就够了-- JVM垃圾回收篇(Garbage Collection)三万字【图文并茂】
文章目录一、基础部分二、垃圾标记阶段引用计数算法(Java未使用)可达性分析算法(Java使用)三、对象的finalization机制一、基础部分1、什么是垃圾(Garbage)呢?垃圾:是指在运行中没有任何指针指向的对象,这个对象就是需要被回收的垃圾。2、为什么需要GC(垃圾回收)呢?(1)如果不及时对内存中的垃圾进行清理,那么,这些垃圾对象所占的内存空会一直保留到应用程序结束,被保留的空间无法被其他对象使用。甚至会导致内存溢出(2)对于一个高级语言来说,如果不进行GC,内存迟早都会被消耗完原创 2020-07-18 23:31:09 · 7832 阅读 · 13 评论 -
垃圾回收--对象的finalization机制、虚拟机中的对象可能的三种状态
1、Java语言提供了对象终止(finalization)机制来允许开发人员提供对象被销毁之前的自定义处理逻辑。2、当垃圾回收器发现没有引用指向一个对象,即:垃圾回收此对象之前,总会先调用这个对象的finalize()方法。3、finalize()方法允许在子类中被重写,用于在对象被回收时进行资源释放。通常在这个方法中进行一些资源释放和清理的工作,比如关闭文件、套接字和数据库连接等。4、永远不要主动调用某个对象的finalize()方法,应该交给垃圾回收机制调用。理由包括下面三点:(1)在执行fi.原创 2020-07-18 22:27:23 · 3933 阅读 · 0 评论 -
深入理解Java虚拟机--执行引擎篇(解释器、JIT编译器)【图文】
以下是针对与HotSpot虚拟机执行引擎的介绍一、执行引擎概述概念:执行引擎是Java虚拟机核心的组成部分,它是用于负责装载字节码到其内部,但是字节码并不能直接在操作系统上运行,那么执行引擎就是将字节码指令解释/编译为对应平台上的本地机器指令。简单来说,JVM执行引擎充当了将高级语言翻译为机器语言的翻译者。二、执行引擎的工作过程1、执行引擎在执行的过程中究竟需要执行什么样的字节码指令安全依赖于PC寄存器。2、每当执行完一项指令操作后,PC寄存器就会更新下一条需要被执行的指令地址。3、当然方法在原创 2020-07-17 17:07:36 · 5027 阅读 · 6 评论 -
Java中堆的内存泄漏和内存溢出OOM 及问题解决 参数设置
首先内存泄漏问题、内存溢出问题可都能会OOM(OutofMemoryError)堆空间不足1、内存泄漏问题导致内存泄漏:是指在堆空间中一直有引用链引用着某些对象。导致对象不能被垃圾收集。解决办法:如果是内存泄漏,课进一步通过工具查看泄漏对象到GC Roots 的引用链。于是就能找到泄漏对象是通过的路径与GC Roots 相关链并导致垃圾收集器无法自动回收它们的。掌握了泄漏对象的类型信息,以及GC Roots引用链的信息,就可以比较准确定位出泄漏代码的位置。2、内存溢出问题导致1) 如果不是内存.原创 2020-07-17 14:45:05 · 15932 阅读 · 1 评论 -
OutofMemoryError的出现原因分析及解决方案内存溢出及泄露
首先报OOM的原因无外乎有两大类:一类是堆空间不足,另一类是元空间不足(直接内存)一、堆空间不足1、内存泄漏问题导致内存泄漏:是指在堆空间中一直有引用链引用着某些对象。导致对象不能被垃圾收集。解决办法:如果是内存泄漏,课进一步通过工具查看泄漏对象到GC Roots 的引用链。于是就能找到泄漏对象是通过的路径与GC Roots 相关链并导致垃圾收集器无法自动回收它们的。掌握了泄漏对象的类型信息,以及GC Roots引用链的信息,就可以比较准确定位出泄漏代码的位置。2、内存溢出导致1) 如果不是内.原创 2020-07-17 14:44:05 · 10602 阅读 · 0 评论 -
JVM堆中对象的对象头的内部结构细节分析及锁状态【图文】
对象头的内部结构一张图了解所有细节1、创建了Customer()实例 和 Account()实例2、对象头里包括:运行时元数据、类型指针、实例数据、对齐填充① 运行时元数据里又包括:哈希值(HashCode)、GC分代年龄、锁状态标志哈希值:它是一个地址,用于栈对堆空间中对象的引用指向,不然栈是无法找到堆中对象的GC分代年龄:记录幸存者区对象被GC之后的年龄age,,一般age为15之后下一次GC就会直接进入老年代锁状态标志:记录一些加锁的信息② 类型指针:是对方法区中类元信息的引用③ .原创 2020-07-17 12:29:39 · 15132 阅读 · 1 评论 -
盘点一下 Java创建对象的几种方式(7大种)全面版
1、new 关键字① 最常见的方式就是直接 new 加构造器的方式创建② 变形一:XXX(类名). 静态方法,本质这种方式还去调用类中构造器,比如说:单例模式、日历类(Calendar) 和一些工具类等等。③ 变形二:XXXBuilder / XXXFactory的静态方法2、Class的newInstance() 反射的方式这种方式jdk9就过时了,为什么呢,就是它只能调用空参构造器,权限必须是是public。3、Constructor的newInstance(XXX),也是反射的方式这种.原创 2020-07-17 11:32:57 · 6908 阅读 · 0 评论 -
Java中创建对象的六个步骤 细分后(new关键字)对象头详细介绍
要看的懂对象的创建过程,首先你得有对Java虚拟机和Java基础以及JUC很是熟悉,比如类的加载过程,CAS、多线程、JVM的GC等等首先好看一个图,我大概会根据图中的内容来分享这六个步骤(其实几个步骤不重要,只要包括的内容都在就行):可以看完这个图就懵了,以下是创建对象的六个步骤:1、判断是否能在常量池中能找到类符号引用,并检查是否已被加载、解析、初始化(即判断类元信息是否存在)如果没有则在双亲委派模式下,使用当前类加载器以ClassLoader + 包名 + 类名为Key进行查找对应的.cl.原创 2020-07-16 22:31:39 · 8659 阅读 · 0 评论 -
Java虚拟机(JVM) 堆、栈、方法区、字符串常量池 的联系【图文】
1、首先我们来看一种创建对象的方式,这代码都见过。但是你知道他们都存在哪里吗?2、再来看一张图你或许就明白了。有用点赞,手留余香!原创 2020-07-15 22:47:35 · 4317 阅读 · 1 评论 -
逃逸分析--代码三大优化策略(堆不是分配对象存储的唯一选择)
堆是分配对象存储的唯一选择吗?答案是:不是的随着JIT编译器的发展与逃逸分析逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化,所以对象都分配到堆上也渐渐变得不是那么绝对了。在Java虚拟机中,对象是在Java堆中分配内存的,这是一个普遍的常识。但是,有一种特殊情况,那就是如果经过逃逸分析后发现,一个对象并没有逃逸出方法的话,那么就可能被优化成栈上分配。这样就无需在堆上分配内存,也无须进行垃圾回收。这也是最常见的堆外存储技术。如何将堆上的对象分配到栈,需要使用逃逸分析手段。Java jdk .原创 2020-07-15 22:07:13 · 4000 阅读 · 0 评论 -
Java虚拟机垃圾回收--Minor GC、Major GC、Full GC
1、JVM在进行GC时,并非每次都对堆中新生代、老年代以及方法区一起回收的,大部分时候回收的都是指新生代中Eden(伊甸园)区。2、针对HotSpot VM的实现,它里面的GC按照回收区域又分为两大类型:一种是部分垃圾收集(Partial GC),一种是整堆收集(Full GC)。3、部分收集:不是完整收集整个Java堆的垃圾收集,其中又分为:① 新生代收集(Minor GC / Yong GC):只是新生代(Eden \ S0 \ S1)的垃圾收集。② 老年代收集(Major GC / Old .原创 2020-07-15 19:54:44 · 13637 阅读 · 0 评论 -
Java类加载器、双亲委派机制及作用、加载不到类所报异常ClassNotFoundException
一、类加载器(Class Loader)1、分类:①启动类加载器(BootStrap);②扩展类加载器(Extension);③应用程序类加载器(Application);④自定义类加载器(Custom).2、双亲委派机制图解:二、双亲委派机制的意义:①防止类的重复加载:防止内存中出现多份同样的字节码。试想,如果没有双亲委派机制模型而是由各个类加载器自行加载的话,如果用户编写了一个java.lang.Object的同名类并放在ClassPath中,多个类加载器都会去加载这个类到内存中,系统中将原创 2020-07-15 15:34:32 · 5656 阅读 · 2 评论 -
方法区元空间实现之jdk7和8字符串常量池、运行时常量池、静态变量到底在哪?
方法区(落地实现jdk7永久代,jdk8元空间),元空间并不在虚拟机中,而是使用本地内存1、此区域是线程共享的。储存已加载的类信息、常量、静态变量、即时编译器编译后的代码等数据;2、常量池:编译器生成的各种字面量和符号引用;3、关于字符串常量池和运行时常量池的位置说明:jdk1.6 存在永久代,字符串常量池、运行时常量池都是在永久代中;jdk1.7 存在永久代,字符串常量池被移动到了堆当中,运行时常量池还是在永久代中;jdk1.8 不存在永久代,实现形式是元空间,字符串常量池仍然在堆当中,运行.原创 2020-07-15 16:27:54 · 5641 阅读 · 14 评论 -
深入理解虚拟机--虚拟机栈篇【图文】
\虚拟机栈1、此区域是线程私有的,生命周期与线程相同。每个方式执行会创建一个栈桢,一个栈桢又包括局部变量表、操作数栈、动态链接、方法返回地址和一些附加信息,其中动态链接、方法返回地址和一些附加信息合起来又叫做桢数据区;2、 局部变量表:①编译期可知的各种基本数据结构、对象引用、返回地址,存储一个局部变量和方法参数。② 基本单位变量槽(varriable Slot): 0位索引的Slot默认是用于传递方法所属对象实例的引用;一个Slot可以存放boolean、byte、char、int、float原创 2020-07-15 17:58:23 · 4083 阅读 · 0 评论 -
深解Java虚拟机(JVM)内存结构各部分总结【三层划分】
文章部分图形来源于尚硅谷,内容仅为个人对JVM的理解,如有错误请批评指正1、第一层:Class文件由类装载子系统(类加载器Class Loader)加载进内存,有三个过程包括加载、链接、初始化。其中链接过程有验证、准备、解析子过程。2、第二层:运行时数据区包括:线程共享区域:方法区(落地实现jdk7永久代,jdk8元空间)、堆线程私有区域:虚拟机栈、本地方法栈、程序计数器3、第三层:执行引擎、本地方法接口(本地方法库)第一层一、过程1、加载:通过类的全限定名来获取定义此类的二进制流;在.原创 2020-07-15 18:00:26 · 6690 阅读 · 8 评论 -
深入理解JVM--堆(Heap)篇【图文】
堆(Heap)1、堆空间是线程共享。那么问题来了,它既然是共享是怎么保证多个线程同时操作引发的安全问题呢?是这样的,堆当中为每一个线程都划分了一个叫做TLAB的区域,以此来保证线程间的操作是安全的。2、堆中又划分为新生代区、老年代区,其中新生代中又划分为Eden(伊甸园区)、幸存者0区(S0)和幸存者1区(S1),幸存者区还可以叫做From区和To区,幸存者From区和To区不是固定的,它们是动态的来回交换的。3、默认新生代中Eden(伊甸园)区、幸存0区和幸存1区多占内存大小比例是8:1:1,新生原创 2020-07-15 18:07:56 · 4076 阅读 · 0 评论 -
Java虚拟机--Class文件加载过程(加载、链接、初始化)
1、加载:通过类的全限定名来获取定义此类的二进制流;在内存中生成一个Class对象,作为方法区该类各种数据的访问入口。获取方式:①从jar、war包中获取;②从网络中获取;③运行时计算机生成:Applet。2、链接:①验证:目的是确保Class文件包含的信息符合虚拟机要求②准备:正式为类变量分配内存并设置类变量零值的阶段(final的变量会赋实际值)。③解析:3、初始化:尚硅谷深解Java虚拟机(JVM)内存结构各部分总结【三层划分】https://blog.csdn.net/q.原创 2020-07-15 18:13:01 · 13146 阅读 · 0 评论