![](https://img-blog.csdnimg.cn/20201014180756724.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
JVM
库昊天
这个作者很懒,什么都没留下…
展开
-
JVM之常见问答
FGC触发时机?老年代空间满;永久代空间满;对象进入老年代的几种情况长期存活对象(生存周期超过设置阈值,默认15);大对象(避免在Young区来回复制);Survivor溢出(Eden和From Survivor存活对象大小超过了To Survivor大小);为什么大对象直接进入老年代?避免大对象在Survivor的回复制,效率低下;防止Survivo...原创 2018-04-07 16:40:03 · 208 阅读 · 0 评论 -
FGC问题排查
问题及原因分类FGC问题分类目前遇到的FGC问题主要分为两大类:FGC频繁(频率高);停顿时间长(FGC持续时间长);FGC原因分类引发FGC问题的原因也主要分为两大类:JVM参数设置不合理;程序Bug;FGC频繁排查JVM参数不合理Young与Old比例不合理Old空间占比过小;Eden与Survivor比例不合...原创 2018-04-09 13:01:47 · 4038 阅读 · 0 评论 -
类加载机制之Launcher
Launcher JVM启动入口,主要作用是:创建ExtClassLoader 、用ExtClassLoader作为parent去创建AppClassLoader、设置AppClassLoader为当前线程的ContextClassLoader,如下图所示: ExtClassLoader ExtClassLoader继承自URLClassLoader,ExtClassL...原创 2017-09-15 09:38:38 · 408 阅读 · 0 评论 -
类加载机制之ContextClassLoader
基础知识点知识点1: 每个ClassLoader都只能加载自己所绑定目录下的资源; 知识点2: 加载资源时的ClassLoader可以有多种选择: 1. 系统类加载器SystemClassLoader,可通过ClassLoader.getSystemClassLoader()获得; 2. 当前ClassLoader:加载了当前类的ClassLoader; 3. 线程...原创 2017-09-16 16:20:19 · 2704 阅读 · 0 评论 -
类加载机制之ClassLoader
基础知识JVM如何区分不同类型? JVM通过类全名+加载该类的ClassLoader区分的;同一个ClassLoader能够重复加载同一个类?同一个ClassLoader不允许多次加载一个类的,否则会报java.lang.LinkageError;JVM只提供了加载类的方法,但并没有提供卸载的方法(主动回收,可预期),当发生FGC时才被回收(被动回收,不可预期);ClassLo...原创 2017-09-15 10:22:09 · 581 阅读 · 0 评论 -
类加载机制之Class.forName()
Class.forName()是Java程序运行时加载类的默认方法,如下图所示: Class.forName()方法解析Class.forName(String className):使用调用Class.forName()方法的类的类加载器加载加载类,如下图所示: Class.forName(String name, boolean initialize,ClassLoad...原创 2017-09-15 11:58:43 · 3690 阅读 · 0 评论 -
JVM类加载机制之类的生命周期
类的生命周期 如下图所示,类的整个生命周期包括了:加载、验证、准备、解析、初始化、使用和卸载这7个阶段。其中,验证、准备和解析这三个部分统称为连接。 加载 加载阶段是将class加载到内存的过程,主要完成以下三件事情:根据类的全限定名查找定义此类的二进制字节流;将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;在Java堆中生成一个代表这个类的java.lang.Class对象原创 2018-04-06 12:54:17 · 298 阅读 · 1 评论 -
JVM类加载机制之双亲委派模型
Java类加载器Bootstrap ClassLoader:根类加载器,负责加载java的核心类,它不是java.lang.ClassLoader的子类,而是由JVM自身实现;Extension ClassLoader:扩展类加载器,扩展类加载器的加载路径是JDK目录下jre/lib/ext,扩展类的getParent()方法返回null,实际上扩展类加载器的父类加载器是根加载器,只是根加载器并原创 2018-04-06 13:26:21 · 1507 阅读 · 0 评论 -
JVM之垃圾回收
对象存活判断判断方式引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。根搜索算法/可达性分析(Reachability Analysis):从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,不可达对象。GC Root原创 2018-04-06 13:58:53 · 137 阅读 · 0 评论 -
跨代引用
什么是跨代引用? 跨代引用是指新生代中存在对老年代对象的引用,或者老年代中存在对新生代的引用,如下图所示: 跨代引用存在问题 YGC时,为了找到年轻代中的存活对象,不得不遍历整个老年代;反之亦然。这种方案存在极大的性能浪费。因为跨代引用是极少的,为了找出那么一点点跨代引用,却得遍历整个老年代!解决方案:记忆集 记忆集就是用来记录跨代引用的表,通过引入记忆集避免遍历老年代...原创 2018-07-30 17:41:58 · 3363 阅读 · 0 评论 -
GC日志打印优化
问题描述 通常我们会设定JVM参数-Xloggc:xxx来指定GC日志文件路径,但是这个日志文件会不断累加,直至进程重启被重新覆盖。因此,对于线上长期运行的应用,输出GC日志性能可能会下降,进而造成JVM停顿,请求RT变大。解决方案:滚动输出打开GC日志滚动记录功能:-XX:+UseGCLogFileRotation;设置滚动日志文件大小:-XX:GCLogFileSize=...原创 2018-08-02 11:55:09 · 1860 阅读 · 0 评论 -
JVM停顿
JVM停顿 JVM在运行过程中,许多事件都可能造成Stop The World,常见的有GC、JIT、取消偏向锁(RevokeBias)、RedefineClasses(AOP)等等,其中GC停顿对应用程序的影响最大。排查手段将JVM停顿时间输出到GC日志中:-XX:+PrintGCApplicationStoppedTime;将JVM停顿原因输出到GC日志中:-XX:+Pr...原创 2018-08-02 14:51:22 · 595 阅读 · 0 评论 -
SHALLOW HEAP和RETAINED HEAP
概念SHALLOW HEAP:对象自身占用的内存大小;Shallow heap of an object is its size in the memory.RETAINED HEAP:对象能够被回收的内存大小,包括了直接引用和间接引用占用的内存;Retained heap is the amount of memory that will be freed when the...原创 2019-01-17 20:41:41 · 557 阅读 · 0 评论 -
应用启动FGC频繁问题排查
现象 应用刚启动的几分钟内固定的发生3次FGC,之后平稳不再GC;GC日志分析 从GC日志可以看出,Metaspace容量达到上限分别触发了一次YGC和FGC,而且Metaspace容量的容量在变大这说明Metaspace容量在不断扩容,这说明Metaspace容量设置过小导致应用启动时发生了扩容,查看JVM参数发现没有显式指定Metaspace容量,默认为20M;GCeasy可视化...原创 2019-01-31 16:33:16 · 1194 阅读 · 0 评论 -
“promotion failed”问题排查
触发时机 YGC时,Survivor空间溢出,溢出部分对象进入老年代时,如果空间不足则抛出“promotion failed”错误。造成影响触发FGC可能原因及方案Survivor空间过小;老年代空间小或者碎片多;原创 2018-04-09 10:35:42 · 3585 阅读 · 1 评论 -
“concurrent mode failure”问题排查
concurrent mode failure是什么? CMS垃圾收集器特有的错误,CMS的垃圾清理和引用线程是并行进行的,如果在并行清理的过程中老年代的空间不足以容纳应用产生的垃圾,则会抛出“concurrent mode failure”。concurrent mode failure影响 老年代的垃圾收集器从CMS退化为Serial Old,所有应用线程被暂停,停顿时间变...原创 2018-04-08 21:00:03 · 2242 阅读 · 0 评论 -
JVM之OutOfMemoryError
OutOfMemoryError类加载:这个类在JVM启动的时候就已经被加载了,而不是在第一次使用时才被加载,可以通过java -verbose:class -version查看JVM是否加载了该类。何时抛出OutOfMemoryError:先尝试内存分配,内存不足则GC,GC之后还是内存不足则抛出OOM。 以堆内存分配为例:正确情况下对象创建需要分配的内存是来自于Heap的Eden区域里,当原创 2017-09-07 17:00:55 · 228 阅读 · 0 评论 -
JVM之Jstat工具原理
原理:从一个叫PerfData的共享文件获取数据,默认是指/tmp/hsperfdata_/这个文件;PerfData文件相关参数: UsePerfData:默认是打开的,如果关闭了UsePerfData这个参数,那么JVM启动过程中PerfData的内存不会被创建; PerfDisableSharedMem:该参数决定了存储PerfData的内存是不是可以被共享。JVM在启动的时候会分原创 2017-09-07 17:28:31 · 816 阅读 · 0 评论 -
JVM之热部署与热加载
预备知识热部署: 就是容器在运行的情况下重新部署整个项目。在这种情况下一般整个内存会清空,、重新加载,但这种方式可能会造成sessin丢失等情况。 热加载: 就是容器状态在运行的情况下重新加载改变编译后的类。在这种情况下内存不会清空、sessin不会丢失,但容易造成内存溢出,或者找不到方法。 热部署与热加载技术想解决的问题是应用升级更新时对业务的影响,分布式集群技术可以允许机器分批重启而不影原创 2017-09-16 17:40:54 · 1023 阅读 · 0 评论 -
JVM监控
JVM监控项JVM监控原理 JDK的java.lang.management包提供了管理接口,用于监控管理JVM及操作系统。如上图所示,JVM有众多监控项,根据JMX规范,每个监控项用MXBean表示,应用程序通过访问MXBean接口获取监控数据。访问方式分为两种:1. 直接访问 通过静态工厂方法直接获取对应的MXBean,然后获取监控数据;2. 间接访问 通过MBeanServe原创 2017-10-24 11:37:43 · 2088 阅读 · 0 评论 -
JIT编译
转载:http://blog.csdn.net/ns_code/article/details/18009455编译过程 不论是物理机还是虚拟机,大部分的程序代码从开始编译到最终转化成物理机的目标代码或虚拟机能执行的指令集之前,都会按照如下图所示的各个步骤进行: 其中绿色的模块可以选择性实现。很容易看出,上图中间的那条分支是解释执行的过程(即一条字节码一条字节码地解释执行,如JavaScri转载 2017-11-21 21:03:57 · 316 阅读 · 0 评论 -
系统预热方案
JIT预热问题:机器重新部署时出现load高、rt高的现象; 原因:重新部署后,JVM需要一段时间识别出热点代码,这段时间内代码都是边解释边执行的,损耗性能。 方案:定制JVM,通过Beta检测出节点代码,生成预热文件,然后推送到集群其它机器,JVM加载到预热文件后将热点代码通过JIT编译成机器代码。原创 2017-11-22 20:46:46 · 1529 阅读 · 0 评论 -
JDK、JRE与JVM关系
JDK Java Development ToolKit(Java开发工具包),JDK是整个JAVA的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)。JRE Java Runtime Enviromental(java运行时环境),包括JVM和JA原创 2017-12-22 09:58:23 · 299 阅读 · 0 评论 -
“一次编译,到处运行”原理
原理 首先,Java源文件按照JVM规范编译成Java字节码(class文件);其次,在不同的操作系统上安装对应的JVM行解释,转换为对应平台的机器码,最终得到执行,如下图所示:原创 2017-12-22 10:56:16 · 1443 阅读 · 0 评论 -
JVM的生命周期
生命周期JVM实例创建当启动一个Java程序时,一个JVM实例就产生了,任何一个拥有public static void main(String[] args)函数的class都可以作为JVM实例运行的起点。 JVM实例运行 main()作为该程序初始线程的起点,任何其他线程均由该线程启动。JVM实例销毁当程序中的所有非守护线程都终止时,JVM才退出;若安全管理器允许,程序也可以使用java.la原创 2017-12-22 14:08:33 · 401 阅读 · 0 评论 -
JVM内存管理
内存模型程序计数器 作用:指示JVM下次执行要执行的字节码指令; 特点:线程私有;虚拟机栈 作用:存储执行Java方法时的堆栈信息,每个方法对应一个帧,存储局部变量等信息; 特点:线程私有;本地方法栈 作用:存储执行native方法时的堆栈信息; 特点:线程私有;堆 作用:存放对象实例; 特点:被所有线程共享,Java堆可以处于物理上不连续的内存空间;方法区 作用:原创 2017-12-23 16:00:32 · 225 阅读 · 0 评论 -
堆外内存
堆外内存定义 创建Java.nio.DirectByteBuffer时分配的内存。堆外内存优缺点 优点: 提升了IO效率(避免了数据从用户态向内核态的拷贝);减少了GC次数(节约了大量的堆内内存)。 缺点:分配和回收堆外内存比分配和回收堆内存耗时;(解决方案:通过对象池避免频繁地创建和销毁堆外内存)为什么堆外内存能够提升IO效率? 堆内内存由JVM管理,...原创 2017-09-06 20:06:51 · 6308 阅读 · 1 评论 -
对象分配与GC过程
对象分配与GC过程创建对象时,优先在Eden区分配;如果对象大小超过-XX:PretenureSizeThreshold指定的值,则直接进入Old区;如果改对象的类首次加载,则加载类信息到方法区;当Eden区满的时候,触发YGC,存活对象存入Survivor区;当Survivor区对象存活时间超过晋升阈值时,长期存活的对象进入Old区;如果YGC存活对象的大小超过Survivor区的剩余容量,原创 2017-12-24 16:57:29 · 444 阅读 · 0 评论 -
Young区与YGC
Young区 Young区被划分为一个Eden区和两个Survivor区。Eden区存放新创建的对象,一个Survivor区存放YGC后存活的对象,另一个为空。为什么分区? 原因:让真正长期存活的对象进入Old区,降低FGC频率。如果不分区,Young区一旦被占满就触发YGC,存活对象进入Old区,即只要能经历一次YGC即可进入Old区,增加了FGC频率。为什么存在两个S原创 2017-12-28 19:11:20 · 977 阅读 · 0 评论 -
垃圾收集器参数调优
JVM调优过程最优参数设置禁止动态调整将新生代和老年代的大小设置为固定,非动态调整的,包括:堆的最大值和最小值相同:-Xms和-Xmx设置为相同的值;新生代的最大值和最小值相同:-Xmn;堆和新生代的大小固定后,老年代的大小也被固定。原因是:动态调整新生代和老年代都会触发FGC,降低吞吐量、增加延时。禁止显式GC参数设置:-XX:+DisableExplicitGC; 原因:代码中显示调用原创 2017-12-24 16:30:20 · 324 阅读 · 0 评论 -
JVM之性能调优
优化指标吞吐量 吞吐量=CPU运行用户代码时间/(GC时间+运行用户代码时间)延迟平均延时(YGC持续时间);平均延时频率(YGC频率);最差延时(FGC持续时间);最差延时频率(FGC频率);内存占用基础准备GC日志GC日志是性能调优及问题排查的基础,常用参数及格式如下所示: OOM内存镜像-XX:+HeapDump...原创 2018-04-07 15:38:50 · 270 阅读 · 0 评论 -
JVM --- MetaspaceSize理解
MetaspaceSize含义 MetaspaceSize容量触发FGC的阈值。比如-XX:MetaspaceSize=256m,当MetaspaceSize容量超过256M时触发FGC,超过设定阈值后MetaspaceSize每扩容一次触发一次FGC;默认值 查看命令如下,默认值大约20.8m;jinfo -flag MetaspaceSize pid设置建议Metaspac...原创 2019-01-31 17:29:17 · 11543 阅读 · 1 评论