JVM
文章平均质量分 87
Java虚拟机相关
壹氿
做一个有准备的人吧~
展开
-
线上项目频繁Full GC问题排查解决
现象发现项目运行一段时间后会莫名其妙的不运行了,没有任何异常日志,好像被hung住了一样,不工作了。排查1、首先查看GC日志,通过jstat -gcutil -t pid 1000 1000查看GC日志,看到FullGC的次数达到了接近两万次。。。并且GC速率没有下降的趋势。2、又通过jmap -heap pid查看堆内存情况,发现Old区Free剩余2M。。3、通过jmap -hsito pid查看哪些类占用的空间多,看到我们自定义的一个类占用很大,因此定位到是我们项目的代码问题。4、通过jma.原创 2021-09-16 10:41:04 · 2910 阅读 · 0 评论 -
GC日志解读,这次别再说看不懂GC日志了
测试环境:机器内存16G,JDK 8,12核CPU测试用例:import java.util.Random;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.LongAdder;/*演示GC日志生成与解读*/public class GCLogAnalysis { private static Random random = new Random(); public static.原创 2021-09-15 10:48:14 · 4630 阅读 · 4 评论 -
JVM GC如何处理跨代引用?(JVM记忆集)
此篇内容来自《深入理解Java虚拟机》跨代引用对象不是孤立的,对象之间会存在跨代引用,假如现在进行一次只局限于新生代区域内的收集(Minor GC),但新生代中的东西是完全有可能被来年代所引用的,为了找出该区域中的存活对象,不得不在固定的GC Roots之外再额外遍历整个老年代中所有的东西来确保可达性分析结果的正确性。JVM将堆内存进行了分代,对象间可能存在跨代引用,那么每次进行GC的时候都需要进行全堆扫描判断是否有引用吗?答案并不是,JVM通过卡表的的技术来解决这个问题。跨代引用假说跨代引.原创 2021-09-09 09:23:33 · 2497 阅读 · 0 评论 -
常见的JVM参数
(后边学习到新的会进行补充)[-XX:MaxTenuringThreshold](提升阈值):对象晋升老年代的阈值,默认值15(并不是绝对的,如果在Survivor空间中相同年龄所有对象大小的综合大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代)[~~-XX:MaxPermSize~~](https://www.yuque.com/lihongjian/fx3n4r/tr10pu#dDqVn):永久代大小[-XX:MaxDirectMemorySize](https://.原创 2021-09-08 20:55:30 · 1935 阅读 · 0 评论 -
即时编译器的代码优化技术
前边讲到了即时编译器将字节码翻译为本地机器码,本文介绍的优化技术是即时编译器在生成代码时采用的代码优化技术方法内联消除方法调用的成本,为其他优化手段建立良好的基础,示例如下,只是举例方法内联的含义,实际优化后肯定不是这样的,还会有其他的优化手段继续优化。//未优化过的代码public class MethodInlining { public static void foo(Object obj){ if(obj == null){ System.原创 2021-09-06 13:38:34 · 309 阅读 · 0 评论 -
类加载的过程有哪些?
一个类的生命周期加载、验证、准备、初始化和卸载这五个阶段的顺序是确定的,解析阶段不一定,它在某些情况下可以在初始化阶段之后再开始。什么时候执行类加载?《Java虚拟机规范》没有明确规定什么事实执行类加载。什么时候执行类的初始化?《Java虚拟机规范》明确规定了有且只有发生以下几种情况必须立即对类进行初始化(加载、验证、准备需要在此之前开始)遇到new、getstatic、putstatic或invokestatic这四条字节码指令时,如果类还没有进行初始化,则进行初始化使用new.原创 2021-08-29 18:02:26 · 253 阅读 · 1 评论 -
String对象与字符串常量池的恩怨情仇
在JVM内存模型章节的常量池部分已经讲过常量池具体都有哪些内容,这篇文章就来详细讲解String字符串常量池。以下绝大部分内容来自知乎R大朋友的回答:https://www.zhihu.com/question/55994121/answer/147296098另推荐一篇文章:https://javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html字符串字面量什么时候进入的字符串常量池?首先上代码,没有什么比代码来的直接//原创 2021-08-19 13:34:14 · 186 阅读 · 0 评论 -
Shenandoah GC---低延迟垃圾收集器
相关概念历史: Shenandoah GC是由 RedHat公司开发的的新型收集器,14年RedHat把Shenandoah贡献给了OpenJDK。设计目标:实现一种能在任何堆内存大小下都可以把垃圾收集的停顿时间限制在十毫秒以内的垃圾收集器。与G1 GC的比较相同点同样基于Region的堆内存布局,同样有着用于存放大对象Humongous Region默认的回收策略也同样是优先处理回收价值最大的Region不同点堆内存管理方面支持并发的整理算法,G1的回收阶段可以是并行的,但.原创 2021-08-09 10:32:28 · 390 阅读 · 0 评论 -
看完这篇,G1垃圾收集器就差不多了~
基础概念定义: Garbage First,垃圾优先,主要面向服务端应用的垃圾收集器。开启命令: -XX:+UseG1GC目标: “停顿时间模型”的收集器:能够支持指定所在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间大概率不超过N毫秒这样的目标。适用场景: 适用于大内存、多CPU的机器。设计理念跳出之前要不收集新生代,要不收集老年代的樊笼,G1面向所有的堆内存任何部分来组成回收集进行回收,衡量标准不再是它属于哪个分代,而是哪块区域中存放的垃圾数量最多,回收效益最大。区域划分Regi.原创 2021-08-04 18:02:02 · 694 阅读 · 0 评论 -
终于把CMS垃圾收集器搞懂了~
相关概念CMS GC的官方名称为“Mostly Concurrenct Mark and Sweep Garbage Collector”(最大-并发-标记-清除-垃圾收集器)。**作用范围:**老年代**算法:**并发标记清除算法。启用参数:-XX:+UseConMarkSweepGC默认回收线程数:(处理器核心数量 + 3)/4Java9之后使用CMS垃圾收集器后,默认年轻代就为ParNew收集器,并且不可更改,同时JDK9之后被标记为不推荐使用,JDK14就被删除了。并发与并行有什么区别?并.原创 2021-07-29 12:19:15 · 805 阅读 · 0 评论 -
常见的垃圾回收算法及细节实现
分代收集理论目前主流的虚拟机的垃圾收集器大多都遵循了“分代收集理论”进行设计。实际上是建立在两个假说的基础上的:弱分代假说(Weak Generational Hy pothesis):绝大多数对象都是朝生夕死(用完即可扔~)强分代假说(Strong Generational Hy pothesis):经过多次垃圾回收都没有被回收掉的对象就越不容易被回收基于上边这两种假说,收集器应该将Java堆划分为不同的区域,然后回收对象依据其年龄生活在不同的区域。也就是将朝生夕死,难以熬过前几次垃圾收集的.原创 2021-07-26 10:59:00 · 348 阅读 · 0 评论 -
记一次使用低版本ES Java Client偶尔查询超时问题解决过程
首先说明项目中ES使用版本为2.4版本,ES JavaClient为2.4.4版本。服务器配置为16G、8核。现象我们一个地区项目中有一个查询ES的接口莫名其妙的翻页会出现超时,可能翻第一页会出现,可能翻第三页会出现。排查思路由于项目没有做任何监控系统,因此唯一的排查思路就是定位到底是哪里执行超时的,在代码中可能发生超时的位置都打了日志并进行临时发布,最后发现是在调用查询ES的时候卡住的(`searchRequestBuilder.execute().actionGet();`),并且没有任何的原创 2021-07-21 10:30:07 · 1075 阅读 · 0 评论 -
HotSpot对象揭秘(对象的创建过程)
对象的创建类加载检查: 虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已经被加载过、解析和初始化过。如果没有,那必须先执行相应的类加载过程。分配内存: 在类加载检查通过后,虚拟机将会非新生对象**分配内存。**对象所需的内存大小在类加载之后就可以确定了,为对象分配空间的过程等同于把一块确定大小的内存从Java堆中划分出来。分配方式有“指针碰撞”,“空闲列表”两种,选择哪种分配方式由Java堆是否规整决定,而Java堆是.原创 2021-07-20 21:29:24 · 278 阅读 · 0 评论 -
JVM运行时数据区(堆、虚拟机栈、本地方法栈、方法区、程序计数器...)
JVM虚拟机规范翻译运行时数据区模型在Java虚拟机中把内存分为若干个不同的数据区域。这些区域有各自的用途,有些区域随着虚拟机进程启动而存在,有些区域则依赖用户线程的启动和结束而建立和销毁。在JVM中主要分为以下几个区域:程序计数器方法区虚拟机栈本地方法栈Java堆程序计数器作用程序计数器内存占用较小,是当前线程执行的字节码的行号指示器。字节码解释器就是通过这个改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环、调整、异常处理、线程恢..原创 2021-07-19 15:30:08 · 608 阅读 · 1 评论 -
JVM虚拟机即时编译与提前编译
即时编译AOT目前主流的两款商用Java虚拟机(HotSpot、OpenJ9)里,Java程序最初都是通过解释器(Interpreter)进行解释执行的,当虚拟机发现某个方法或者代码块的运行特别频繁,就会把这些代码认定为“热点代码”(Hot Spot Code),为了提高代码的执行效率,在运行时,虚拟机将会把这些代码编译成本地机器码,并以各种手段尽可能地进行代码优化,这个过程称为即时编译。提前编译JIT提前编译是相对于即时编译的概念,提前编译能带来的最大的好处是Java虚拟机加载这些已经预编译成二.原创 2021-07-19 15:26:09 · 626 阅读 · 1 评论