JVM
文章平均质量分 85
鮀城小帅
在工作中一步步学习、进步,充实工作也充实生活。
展开
-
JVM:33 如何查看JVM的Full GC日志
1. 示例代码package com.webcode;public class Demo4 { public static void main(String[] args){ byte[] array1 = new byte[4 * 1024 * 1024]; array1 = null; byte[] array2 = new byte[2 * 1024 * 1024]; byte[] array3 = new byte[2 * 1024 * 1024]; byte[]原创 2021-10-06 13:25:48 · 3873 阅读 · 0 评论 -
JVM:32 实验:模拟对象进入老年代的场景
1.动态年龄判定规则对象进入老年代的4个常见的时机:躲过15次gc,达到15岁高龄之后进入老年代; 动态年龄判定规则,如果Survivor区域内年龄 1+ 年龄2 +年龄3+年龄n的对象总和大于Survivor区的50%,此时年龄n以上的对象会进入老年代,不一定要达到15岁 如果一次Young GC后存活对象太多无法放入 Survivor 区,此时直接进入老年代 大对象直接进入老年代(1)动态年龄判定规则进入老年代首先模拟最常见的一种进入老年代的情况,如果Survivor区域内年龄1 +原创 2021-09-25 17:13:18 · 523 阅读 · 1 评论 -
JVM:31 硬核技能:JVM的Young GC日志查看方法
1. 程序运行采用的默认JVM参数如何查看?在GC 日志中,可以看到如下内容:CommandLine flags: -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:MaxNewSize=5242880 ……这就是告诉你这次运行程序采取的JVM参数是什么,基本都是我们设置的,同时还有一些参数默认就给设置了,不过一般关系不大。如果没有设置JVM参数,而想看系统用的默认JVM参数,只需要给JVM加一段打印GC日志的参数,就可以原创 2021-09-16 23:23:40 · 715 阅读 · 1 评论 -
JVM:30 实验:模拟频繁Young GC的场景
1. 程序的JVM参数示范已知,平时系统运行创建的对象,除非是那种大对象,否则通常来说都是优先分配在新生代中的Eden区域的。而且新生代还有另外两块Survivor区域,默认Eden区域占据新生代的80%,每块Survivor区域占据新生代的10%。比如我们用以下JVM参数来运行代码:-XX:NewSize=5242880 -XX:MaxNewSize=5242880 -XX:InitialHeapSize=10485760 -XX:MaxHeapSize=10485760 -XX:Sur原创 2021-09-16 22:17:04 · 373 阅读 · 0 评论 -
JVM:29 面试题:Young GC和Full GC分别在什么情况下会发生?
1.Young GC\Old GC\Full GC的定义Young GC是年轻代的GC,Old GC就是老年代的GC,Full GC是针对年轻代、老年代、永久代进行的整体的GC。此外还有几个其他的名词跟他们有重叠的含义,比如Minor GC也可以称之为Young GC,Major GC也可以称之为Old GC,有的人也把Major GC和Full GC划等号,也有人把Full GC和Old GC划等号。同一概念,Young GC指代年轻代GC,用Old GC指代老年代GC,用Full GC指代年原创 2021-09-13 21:52:40 · 2208 阅读 · 0 评论 -
JVM:28 面试题:解释一下什么是Young GC和Full GC?
(1)Minor GC / Young GC“新生代” 也可以称之为 “年轻代” ,这两个名词是等价的。在年轻代中的Eden内存区域被占满之后实际上就需要出发年轻代的GC,或者是新生代的GC。此时这个新生代GC,就是所谓的 “Minor GC”,也可以称之为“Young GC”,这两个名词,都是针对新生代的GC。(2)Full GC / Old GC之前分析过,老年代一旦被占满之后,就会触发老年代的GC,之前称呼这种GC为Full GC。所谓老年代的GC,称之为 “Old GC” 更加合原创 2021-09-13 07:17:50 · 3347 阅读 · 0 评论 -
JVM:27 实战:线上系统卡死无法访问问题排查
1. 基于JVM运行的系统最怕的是什么?JVM运行的时候,最核心的内存区域,就是堆内存区域,这里会放各种我们系统中创建出来的对象。堆内存里通常都会划分为新生代和老年代两个内存区域,对象一般来说都是优先放在新生代的。随着系统不停的运行,会有越来越多的对象放入年轻代中,然后年轻代会塞满,而放不下更多的对象。这时候就需要清理一下年轻代的垃圾对象,也就是那些没有GC Roots引用的对象。所谓的GC Roots就是类的静态变量,方法的局部变量。平时创建对象的地方,就是在方法里,但是一旦一个方原创 2021-09-13 06:49:17 · 580 阅读 · 0 评论 -
JVM:26 案例:百万级用户的在线教育平台,如何基于G1垃圾回收器优化性能?
1. 案例背景案例的背景,是一个百万级注册用户的在线教育平台,主要目标用户群体是几岁到十几岁的孩子,注册用户大概是几百万的规模,日活用户规模大概在几十万。其业务包括选课、排课、浏览课程以及付费购买之类的低频的行为。此外最核心也最为主要的高频行为是 “上课” 。从该课程面向的群体来说,主要是幼儿园的孩子到中小学的孩子。所以这些群体最活跃使用该平台的时候主要集中在晚上放学之后到八九点之间。以及周末也是最活跃使用该平台的时候。由此,可以知道,每天晚上那两三小时的高峰期,有将近几十万日活用户集中在该原创 2021-09-12 19:25:54 · 316 阅读 · 0 评论 -
JVM:25 线上系统部署采用G1垃圾回收器,如何设置参数?
1. 什么时候出发新生代 + 老年代的混合垃圾回收?G1 有个参数,是 “-XX:InitiatingHeapOccupancyPercent” ,默认值是45%。意思是老年代占据了堆内存的45%的 Region时,就会触发一个新生代 + 老年代一起回收的混合回收阶段。2. G1垃圾回收的过程首先会触发一个 “初始标记” 操作,这一过程需要进入 STW,但仅仅是标记一下 GC Roots 直接能引用的对象,速度是很快的。整个过程是,先停止系统程序的运行,然后对各个线程栈内存中的局部变量代表的原创 2021-09-12 14:52:42 · 1032 阅读 · 0 评论 -
JVM:24 G1分代回收原理深度图解:为什么回收性能比传统GC更好?
1. 如何设定G1对应的内存大小已知 G1对应的是一大堆的 Region 内存区域,每个 Region 的大小是一致的。问题:到底有多少个Region呢?每个Region的大小是多大呢?Region的数量和大小,在默认情况下是自动计算和设置的。也可以给整个堆内存设置一个大小,比如说用 “-Xms” 和 “-Xmx” 来设置堆内存的大小。然后JVM启动的时候一旦发现你使用的是G1垃圾回收器,可使用 “-XX:+UseG1GC” 来指定使用 G1垃圾回收器,此时会自动用堆大小除以2048。原创 2021-09-12 13:54:59 · 489 阅读 · 0 评论 -
JVM:23 面试题:G1垃圾回收器的工作原理
1. ParNew + CMS的组合有哪些痛点?ParNew + CMS 两个垃圾回收器对新生代和老年代进行垃圾回收的运行过程中,都会或多或少产生 STW 现象,对系统的运行是有一定影响的。而为了减少 STW ,G1垃圾回收器应运而生,他可以提供比 “ParNew + CMS” 组合更好的垃圾回收的性能。2. G1垃圾回收器G1垃圾回收器可以同时回收新生代和老年代的对象,不需要两个垃圾回收器配合起来运作。G1垃圾回收器最大的特点,是把Java堆内存拆分为多个大小相等的 Region(范围原创 2021-09-12 11:29:58 · 1818 阅读 · 1 评论 -
JVM:22 知识点扩展-面试题
1. 如果在Tomcat部署多个服务,JVM启动个数是根据服务来算,还是根据tomcat来算的?答: 一个Tomcat启动多个Web应用,那JVM只有一个,就是Tomcat自己,你的Web应用都是一堆代码,由Tomcat根据配置文件来对指定的请求调用你的代码。2. Minor GC、Major GC和Full GC这几个概念到底有什么区别?Minor GC怎么也会STW?答:不管是老年代回收还是新生代回收,都要Stop the World,因为必须让程序别创建新对象,才能回收垃圾对象。Ful原创 2021-09-12 10:58:58 · 123 阅读 · 0 评论 -
JVM:21 每日请求上亿的电商系统,老年代的垃圾回收参数该如何优化?
1. 年轻代JVM优化回顾在每日百万日活以及上亿请求量的电商系统的案例中,在大促期间的瞬时高峰下单场景下,JVM优化分析后,得出在大促高峰期,每秒每台机器会有300个下单请求。进而推测出每秒钟会使用60MB的内存,根据这个背景推算出了一台4核8G的机器上,应该如何合理的给JVM各个区域分配内存。进而可以保证每隔20多秒一次新生代GC后的100MB左右的存活对象,会进入200MB的Survivor区域内,一般不会因为Survivor塞不下或者是动态年龄判定规则让对象进入老年代中。同时还根据 M原创 2021-09-12 09:43:16 · 324 阅读 · 0 评论 -
JVM:20 案例:每日上亿请求量的电商系统,年轻代垃圾回收参数如何优化?
1. 案例背景背景为电商系统,电商系统一般拆分为多个子系统独立部署,这里以核心的订单系统为例子说明。假设该电商系统每日上亿请求量,按照每个用户平均访问20次计算,大致需要有500万日活用户。在按照10%的付费转化率计算,每天大概有50万人会下订单,也就是每天会有50万订单。如果这50万订单集中在每天4个小时的高峰期内,平均算下来就是每秒钟大概有几十个订单。而这种几十个订单的压力,基本上每秒钟占用一些新生的内存,要很久新生代才会满,然后一次Minor GC后垃圾对象清理掉,内存就空出来了,几乎原创 2021-09-11 23:01:25 · 358 阅读 · 0 评论 -
JVM:19 线上部署系统时,如何设置垃圾回收相关参数?
1. 回顾CMS的 STW为了避免长时间STW,CMS采用了4个阶段来垃圾回收,其中初始标记和重新标记,耗时很短,虽然会导致 “Stop the World” ,但是影响不大。然后并发标记和并发清理,两个阶段耗时最长,但是可以跟系统的工作线程并发运行,所以对系统没有太大影响。这就是CMS的基本工作原理。2.并发回收垃圾导致CPU资源紧张如图,由于在垃圾回收的并发标记和并发清理两个阶段,同时让系统同时工作,会导致有限的CPU资源被垃圾回收线程占用了一部分。并发标记的时候, 需要对G原创 2021-09-11 21:33:09 · 223 阅读 · 0 评论 -
JVM:18 JVM老年代垃圾回收器CMS的内部工作机制
1. CMS垃圾回收的基本原理一般老年代选择的垃圾回收器是CMS,采用的是标记清理算法。采用标记方法去标记出哪些对象是垃圾对象,然后就把这些垃圾对象清理掉。上图,是一个老年代内存区域的对象分布情况,假设因为老年代内存空间小于了历次Minor GC后升入老年代对象的平均大小,判断Minor GC有风险,可能就会提前触发Full GC回收老年代的垃圾对象。或者是一次Minor GC的对象太多了,都要升入老年代,发现空间不足,触发了一次老年代的Full GC。也就是执行一次标记-清理算法。该算原创 2021-09-11 20:54:18 · 1248 阅读 · 0 评论 -
JVM:17 深入理解JVM的年轻代回收器ParNew是如何工作的?
1. 最常用的新生代垃圾回收器: ParNew在没有G1垃圾回收器之前,线上系统使用的都是ParNew垃圾回收器作为新生代的垃圾回收器。即使现在有了G1,很多线上系统还是用的ParNew。通常运行在服务器上的Java系统,都可以充分利用服务器的多核CPU的优势。假设你的服务器是4核CPU,如果对新生代垃圾回收的时候,仅仅使用单线程进行垃圾回收,就会导致没法充分利用CPU资源。如上图,现在在垃圾回收的时候,都把系统程序所有的工作线程全部停掉了,就一个垃圾回收线程在运行。那么此时4核C.原创 2021-09-11 18:10:22 · 610 阅读 · 0 评论 -
JVM:16 扩展知识点-面试题
1. 面试题:parnew+cms的gc,如何保证只做ygc,jvm参数如何配置答:关键点是必须让Survivor区能放下所有存活对象,而且不能因为动态年龄判定规则直接升入老年代。然后只要Survivor区可以放下,那么下次Minor GC后还是存活那么多对象,依然可以在另外一块Survivor区放下,基本就不会有对象升入老年代里去。参考方案:加大分代年龄,比如默认15加到30; 修改新生代老年代比例,比如新生代老年代比例改为2:1 修改e区和s区比例,比如改成6:2:22. 内存地址可变原创 2021-09-11 17:03:04 · 147 阅读 · 0 评论 -
JVM:15 “Stop the World”问题分析
1. 新生代GC场景新生代的内存分为Eden和两个Survivor的。如果系统不停的运行,最终会把Eden给塞满。一旦Eden塞满,就会触发Minor GC,而进行垃圾回收是有专门的垃圾回收线程的,不同的内存区域会有不同的垃圾回收器 。简单来说,就是垃圾回收线程和垃圾回收器配合起来,使用自己的垃圾回收算法,对指定的内存区域进行垃圾回收,如下图:...原创 2021-09-11 15:15:39 · 1219 阅读 · 0 评论 -
JVM : 14 面试题:JVM中都有哪些常见的垃圾回收器,各自的特点是什么?
1. 案例:一个日处理上亿数据的计算系统案例的背景,有一个数据计算系统,日处理数据量在上亿的规模。这个系统会不停的从MySQL数据库以及其它数据源里提取大量的数据,加载到自己的JVM内存里来进行计算处理,如下图所示:这个数据计算系统会不停的通过SQL语句和其他方式从各种数据存储中提取数据到内存中来进行计算,大致当时的生产负载是每分钟大概需要执行500次数据提取和计算的任务。但是这是一套分布式运行的系统,所以生产环境部署了多台机器,每台机器大概每分钟负责执行100次数据提取和计算的任务。原创 2021-09-11 14:23:03 · 458 阅读 · 0 评论 -
JVM : 13 面试题:年轻代和老年代分别适合什么样的垃圾回收算法?
1. 新生代里的对象一般在什么场景下会进入老年代?代码在运行的过程中,会不断的创建各种各样的对象,这些对象都会优先放到新生代的 Eden区和 Survivor1区。接着假如新生代的 Eden区和 Survivor1区都快满了,此时就会触发Minor GC,把存活对象转移到 Survivor2区去。如下图所示:然后接着会使用 Eden区和Survivor2区,来分配新的对象,如下图所示:2. 躲过15次GC之后进入老年代在上面的流程中,随着系统的运行,新生代逐渐满了,就会触发.原创 2021-09-09 23:35:09 · 1670 阅读 · 0 评论 -
JVM : 12 面试题:JVM中有哪些垃圾回收算法,每个算法各自的优劣?
主题:新生代进行垃圾回收的时候,到底是采取一种什么样的算法进行的呢?1.复制算法的背景引入针对新生代的垃圾回收算法,叫做复制算法。新生代的内存分为两块,如下图:假设有如下代码,在 “loadReplicasFromDisk()” 方法中创建了对象,此时对象就会分配在新生代其中一块内存空间里。而且由 “main线程” 的栈内存中的 “loadReplicasFromDisk()” 方法的栈帧内的局部变量来引用的,如下图所示:假设此时,代码在不停的运行,然后大量对象都分配在了原创 2021-09-07 20:47:10 · 239 阅读 · 0 评论 -
JVM : 11 面试题:什么情况下JVM内存中的一个对象会被垃圾回收?
1. 什么时候会触发垃圾回收?系统运行创建的对象都是优先分配在新生代里的,如下图:如果新生代里的对象越来越多,都快满了,此时就会触发垃圾回收,把新生代没有人引用的对象给回收掉,释放内存空间。2. 被哪些变量引用的对象是不能回收的?在JVM中使用了一种可达性分析算法来判定哪些对象是可以被回收的,哪些对象是不可以被回收的。该算法的意思,是对每个对象,都分析一下有谁在引用它,然后一层一层往上去判断,看是否有一个GC Roots。如上述代码,它是在一个方法中创建了一个对象,然后有原创 2021-09-05 21:54:39 · 498 阅读 · 0 评论 -
JVM : 10 案例:每日百万交易的支付系统,JVM栈内存与永久代大小又该如何设置?
1. 不合理设置内存的反面示例比如,支付系统因为没有经过合理的内存预估,所以选用了 1台2核4G的虚拟机来部署了线上系统,而且就只用了一台机器。然后线上JVM给的堆内存大小,仅仅就只有1G,扣除老年代之后,新生代其实就几百MB的内存空间,如下图。按照每天100万交易,高峰值为每秒大概100笔支付交易,对应核心的支付订单对象有100个创建出来,每个支付订单对象占据500左右的字节大小,总共就是50kb大小。然后一笔交易要1秒来处理,所以这100个对象在新生代中存在1秒的期间会被引用,是无法原创 2021-09-05 20:49:02 · 365 阅读 · 0 评论 -
JVM : 9 案例:每日百万交易的支付系统,如何设置JVM堆内存大小
1.支付系统背景在一个电商系统里,一个支付系统如下图所示:网购的大致流程是,在APP或网站上购买东西,一般是将一些商品添加到购物车里,然后下订单,接着对订单进行支付,钱从我们的账户划拨到网站的账户里去。在上述的过程中,有个支付系统,它是网站或APP后台系统的核心环节,负责管理公司的资金流。它负责对接用户支付的请求,然后根据用户的扣款方式,跟第三方的支付渠道对接起来,比如微信、支付宝,等等。2. 支付的核心业务流程上图的业务流程如下:首先用户在商城系统提交支付一个订单的请.原创 2021-09-05 18:17:25 · 575 阅读 · 0 评论 -
JVM : 8 线上部署时如何设置JVM内存大小
1. JVM内存相关的几个核心参数在 JVM 内存分配中,有以下几个参数比较核心:-Xms: Java堆内存的大小 -Xmx:Java堆内存的最大大小 -Xmn:Java堆内存中的新生代大小,扣除新生代剩下的就是老年代的内存大小了 -XX:PermSize:永久代大小 -XX:MaxPermSize:永久代最大大小 -Xss:每个线程的栈内存大小参数说明:-Xms 和 -Xmx,分别用于设置 Java 堆内存的初始值大小,以及最大能扩展的内存大小。建议设置为一样的大小,减少内存提升的原创 2021-09-05 17:09:28 · 1233 阅读 · 0 评论 -
JVM : 7 对象在JVM内存中如何分配与流转?
1. 两种对象代码里创建出来的对象,一般有如下两种:一种是短期存活的,分配在 Java 堆内存之后,迅速使用完就会被垃圾回收; 另外一种是长期存活的,需要一直生存在 Java 堆内存里,让程序后续不停的去使用前者的对象,是在 Java 堆内存的新生代里;而后者的对象,是在 Java 堆内存的老年代里。2. 大部分正常对象都优先在新生代分配内存问题:对象肾情况下短期存活?要知道,大部分正常对象,都优先在新生代分配内存的。按上一章所说,类静态变量 "fetcher" 引用的 “.原创 2021-09-05 16:02:53 · 349 阅读 · 0 评论 -
JVM : 6 JVM分代模型:年轻代、老年代、永久代
1. 背景引入JVM内存的分代模型: 年轻代、老年代、永久代。我们在代码里创建的对象,都会进入到 Java 堆内存中,方法的栈帧都会压入到Java虚拟机栈里,而方法如果有局部变量,该局部变量就会在方法所对应栈帧里去引用Java对列出里的对象实例。最终,就会执行该对象的方法。比如上图的 ReplicaManager对象的 load() 方法。2. 大部分对象都是存活周期极短的上述的代码中, ReplicaManager 对象,是属于短暂存活的一个对象。当最终执行到 replicaM原创 2021-09-05 15:28:00 · 701 阅读 · 0 评论 -
JVM : 5 知识点归纳
1. 方法走完,引用消失,堆内存未必消失。个别在做报表导出的逻辑中,会在 for 循环里不断的创建对象,很容易造成对溢出。面对上述的问题,建议不要在for 里创建对象,可以在外面搞一个对象, for 循环里对一个对象修改数据即可。2. Java支持多线程,每个线程都有自己的 Java 虚拟机栈和本地方法栈。新建的实例在堆内存,实例变量也在堆内存。3. 所谓出栈、入栈,入栈,就是你执行一个方法的时候,为这个方法创建一个栈帧入栈;出栈,就是方法执行完毕了,就会出栈。4. 父类子类的情况下,加载顺原创 2021-09-02 23:10:36 · 121 阅读 · 0 评论 -
JVM : 4 JVM的垃圾回收机制
1. 对象的分配与引用有如下一段代码,通过 “loadReplicasFromDisk” 方法的执行,去磁盘上加载需要的副本数据。然后通过 “ReplicaManager” 对象实例完成这个操作。根据 JVM运行原理,上述代码的运行流程如下:首先一个 main 线程肯定会来执行 main() 方法里的代码,main 线程有一个Java虚拟机栈, 会把 main() 方法的栈帧压入 Java 虚拟机栈。接着 main() 方法里调用了 loadReplicasFromDisk()方法。原创 2021-09-02 22:10:23 · 213 阅读 · 0 评论 -
JVM : 3 JVM的内存区域划分与职能
1. 什么是JVM 的内存区域划分JVM在运行写好的代码时,必须使用多块内存空间,不同的内存空间用来放不同的数据,然后配合写的代码流程,才能让系统运行起来。JVM里必须有一块内存区域,用来存放写的那些类;其次,在运行方法的时候,方法里的很多变量,也需要放在内存区域里;再有就是,写的代码里创建一些对象,他们也需要内存空间来存放。以上,就是JVM必须划分不同的内存区域的原因。2. 存放类的方法区JDK1.8以前的版本里,方法去代表JVM中的一块区域。主要是放从 “.class” 文件里加原创 2021-09-01 22:24:00 · 216 阅读 · 0 评论 -
JVM : 2 JVM类加载机制
1. 类加载过程图示从上图的“类加载” 过程,去看看 JVM的类加载机制是什么原理?2. JVM 在什么情况下会加载一个类一个类从加载到使用,会经历如下的过程:加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载JVM在执行写好的代码时,在代码中用到这个类的时候,就会从 “.class” 字节码文件中加载这个类到 JVM 内存里来。3. 验证、准备和初始化(1)验证阶段验证,就是根据 Java 虚拟机规范.原创 2021-09-01 06:48:01 · 156 阅读 · 0 评论 -
JVM虚拟机 与 GC 垃圾回收
一、JVM体系结构概述1、JVM 与系统、硬件 JVM是运行在操作系统之上的,它与硬件没有直接的交互2、JVM 体系结构概览 3、类装载器ClassLoader 执行原理负责加载class文件,class文件在文件开头有特定的文件标示,并且ClassLoader只负责class文件的加载,至于它是否可以运行,则...原创 2020-02-12 15:55:38 · 471 阅读 · 0 评论