悟纤
过着爱谁谁的生活,活出不设限的人生!
展开
-
JVM内存模型和性能调优:为什么要学习JVM
一图就可以搞明白:原创 2020-04-13 14:35:39 · 27443 阅读 · 0 评论 -
JVM内存模型和性能调优:系列文章 - 导读
学习 Java 虚拟机能深入地理解 Java 这门语言,想要深入学习java的各种细节,很多时候你要深入到字节码层次去分析,你才能得到准确的结论,通过学习JVM你了解JVM历史,内存结构、垃圾回收机制、性能监控工具、认识类的结构体,Java的编译运行优化、字节码剖析等。课程目标 本课程专门针对于JVM的执行流程、内存分配、垃圾收集等机制进行了综合讲解。...原创 2020-04-13 14:10:03 · 27619 阅读 · 0 评论 -
JVM内存模型和性能调优:什么是Java虚拟机 - 第1篇
前言 我们知道在Windows系统上的软件安装包是exe文件,在Mac OSX系统上是dmg文件,exe在mac是无法安装的,同样dmg文件在window下也是无法安装的。 为什么不同系统上的软件无法安装,这是因为操作系统底层的实现是不一样的。对于 Windows 系统来说,exe 后缀的软件代码最终编译成 Windows 系统能识别的机器码。而 Mac OSX 系...原创 2020-04-13 15:49:23 · 27103 阅读 · 0 评论 -
JVM内存模型和性能调优:一图了解JVM核心组成 - 第2篇
前言 在前一节,我们说了JVM就是一个字节码翻译器,翻译成不同系统的机器码,那么的核心构成是什么呢?一、JVM核心组成 通过上图我们可以看出JVM有三大核心部分组成:类加载子系统、字节码执行引擎、运行时数据区。(1)类加载子系统:在JAVA虚拟机中,负责查找并装载类的。(2)字节码执行引擎:顾名思义就是执行字节码指令的。(3)运行时数...原创 2020-04-13 15:52:18 · 27199 阅读 · 0 评论 -
JVM内存模型和性能调优:类加载过程 - 第3篇
前言 在前面我们介绍了JVM的核心三部分:类加载器、字节码解释器、运行时数据区。 这一节我们来介绍下类加载器。一、类加载过程多个java文件经过编译打包生成可运行jar包,最终由java命令运行某个主类的main函数启动程序,这里首先需要通过类加载器把主类加载到JVM,主类在运行过程中如果使用到其它类,会逐步加载这些类。注意:对于我们自己写的j...原创 2020-04-13 15:57:07 · 27892 阅读 · 0 评论 -
JVM内存模型和性能调优:深入理解加载和初始化 - 第4篇
前言 前面对于类加载过程有了一定的认知,在几个过程中,加载和初始化是比较重要的,也是面试喜欢问的。一、类的加载1.1 概念JVM主要完成三件事:(1)通过一个类的全限定名(包名与类名)来获取定义此类的二进制字节流(Class文件)。而获取的方式,可以通过jar包、war包、网络中获取、JSP文件生成等方式。(2)将这个字节流所代表的静态存储结构转化为方法区...原创 2020-04-13 16:02:58 · 27344 阅读 · 0 评论 -
JVM内存模型和性能调优:类加载器 - 第5篇
前言前面讲到的类加载过程主要是通过类加载器来实现的。一、类加载器Java里有如下几种类加载器:(1)启动类加载器(BootstrapClassloader):负责加载支撑JVM运行的位于JRE的lib目录下的核心类库,比如rt.jar、charsets.jar等。(2)扩展类加载器(ExtClassLoader):负责加载支撑JVM运行的位于JRE的lib目录下的ext扩...原创 2020-04-14 17:06:01 · 27116 阅读 · 0 评论 -
JVM内存模型和性能调优:自定义类加载器- 第6篇
前言在前面介绍了Java中的几种常见的类加载,还有一种自定义的类加载器,那么我们怎么定义呐?一、自定义类加载器 我们自定义类加载器MyClassLoaderTest:public class MyClassLoaderTest { static class MyClassLoader extends ClassLoader { priv...原创 2020-04-14 17:07:16 · 27342 阅读 · 0 评论 -
JVM内存模型和性能调优:双亲委派机制- 第7篇
前言 在前面我们学习了这个Java的几个类加载,我们也自定义了一个我们自己的类加载器,那么这些类加载之间有关系嘛?一、双亲委派机制1.1 概念JVM类加载器是有亲子层级结构的,如下图:这里类加载其实就有一个双亲委派机制,加载某个类时会先委托父加载器寻找目标类,找不到再委托上层父加载器加载,如果所有父加载器在自己的加载类路径下都找不到目标类,则在自己的类加载...原创 2020-04-14 17:09:59 · 27195 阅读 · 0 评论 -
JVM内存模型和性能调优:打破双亲委派- 第8篇
前言 上面我们介绍了类加载器的双亲委派机制,那么这个机制是否可以被打破呐,答案是可以的。一、Tomcat打破双亲委派机制分析1.1 Tomcat使用默认类加载可行性分析?问题:以Tomcat类加载为例,Tomcat 如果使用默认的双亲委派类加载机制行不行? 我们思考一下:Tomcat是个web容器, 那么它要解决什么问题:(1)一个web容器...原创 2020-04-16 14:01:39 · 27134 阅读 · 0 评论 -
JVM内存模型和性能调优:打破双亲委派的实现- 第9篇
前言 我们上面分析了tomcat通过打破双亲委派机制实现了隔离性。那我们自己要怎么实现呐。一、如何打破双亲委派机制 那我们分析下我们这个MyClassLoaderTest这个加载类的过程:(1)从main的classLoader.loadClass()进行加载我们指定的类。Class clazz = classLoader.loadClass("...原创 2020-04-16 14:04:13 · 27174 阅读 · 0 评论 -
JVM内存模型和性能调优:JVM整体结构及内存模型- 第10篇
在接下来的课程中,我们就是对上面这张图片展开进行讲解。(1)类加载子系统:就是上面我们讲过的类加载器做的事情。(2)字节码执行引擎:顾名思义就是执行字节码指令的。(3)运行时数据区:Java虚拟机在执行Java程序过程中会把内存区域划分为若干个不同的数据区域,这些区域统称为运行时数据区。(4)栈(线程):栈是运行时单位,栈是线程私有的,所以称为线程栈。栈(Stack)...原创 2020-04-17 17:06:26 · 27119 阅读 · 0 评论 -
JVM内存模型和性能调优:栈(线程)- 第11篇
前言 栈是线程运行的单位,那接下我们不会讲太多概念性的东西,主要是通过Math.java这个类和大家分析学习。一、线程栈分析 我们看下Math.java类:public class Math { public static int initData = 666; public int compute(){// int...原创 2020-04-17 17:11:30 · 27396 阅读 · 0 评论 -
JVM内存模型和性能调优:栈大小分析- 第12篇
前言 前面我们对于栈有一个基本的认知了,栈核心的是有栈帧控制的,一个方法就会分配一个栈帧内存空间,这个栈空间,是否可以可以无限开辟栈帧内存空间,答案肯定是不可以的,想必大家都有碰到过栈内存溢出吧。一、Xss(Stack Size)设置方式就是:JVM设置 -Xss160k ,默认的大小是1M,接下里我们看个小栗子StackOverFlowTest: public c...原创 2020-04-19 14:04:30 · 27188 阅读 · 2 评论 -
JVM内存模型和性能调优:堆/栈/方法区的关系- 第13篇
前言 这节我们要把这些之间的关系串起来。一、关系梳理 通过前面的梳理我们知道了:(1)栈中的变量如果是引用类型的变量,那么会指向存放的对象的堆地址。(2)堆中的对象的地址会指向元空间的对应的类元信息。(3)元空间的静态变量会指向堆的地址。元空间在jdk1.8+之后,就直接存储在直接内存了,在以前是存放在JVM的一个持久代内存区域中的。...原创 2020-04-19 14:06:13 · 27204 阅读 · 0 评论 -
JVM内存模型和性能调优:解析/静态链接/动态链接- 第14篇
前言 在前面我们还遗留了一些问题没有讲到:(1)类加载过程中的解析更深层次的意思(2)静态链接(3)动态链接 因为这些定义会比较抽象,所以我们这里放在一起进行讲解。一、解析/静态链接/动态链接1.1 解析解析:将符号引用替换为直接引用,该阶段会把一些静态方法(符号引用,比如main()方法)替换为指向数据所存内存的指针或句柄等(直接引用...原创 2020-04-19 14:08:56 · 27597 阅读 · 0 评论 -
JVM内存模型和性能调优:堆内存空间- 第15篇
前言 在前面我们把JVM几大块都讲了差不多了,生下来就是最核心,也是优化最多的地方,就是堆内存。一、堆内存1.1 堆内存概念对于堆空间你要找到这么几点:堆内存分两大块:年轻代(新生代)和老年代,它们的空间大小的比率是1:2,那么年轻代就是占了1/3,老年代占了2/3。 年轻代由两块区域组成:Eden和Survivor, E:S = 8:2 。 Surv...原创 2020-04-19 14:10:00 · 27278 阅读 · 0 评论 -
JVM内存模型和性能调优:堆内存空间-案例分析- 第16篇
前言 前面介绍了这个堆内存空间,我们还是通过具体的案例来理解下对象复制的过程吧。一、案例分析1.1 示例我们看一段代码HeapTest:public class HeapTest { byte[] b = new byte[1024*100]; // 100KB public static void main(String[] args) t...原创 2020-04-19 14:11:15 · 27067 阅读 · 0 评论 -
JVM内存模型和性能调优:Eden Survivor名称由来- 第17篇
前言 这一节我们来讲有趣的故事,有助于大家对于堆中的这些有一定的了解。一、名词Eden:含义:伊甸园(The garden of Eden)Survivor:含义:幸存者GC:含义:Garbage CollectionStop the world event含义:地球停转事件,简称STW,即在执行垃圾收集算法时,Java应用程序的其他所有除...转载 2020-04-20 16:51:46 · 27660 阅读 · 4 评论 -
JVM内存模型和性能调优:JVM的新生代内存中,为什么除了Eden区,还要设置两个Survivor区?- 第18篇
前言 Java为什么要设计Survivor,而且还要设计两个呐?一、为什么要有Survivor区如果没有Survivor,Eden区每进行一次Minor GC,存活的对象就会被送到老年代。老年代很快被填满,触发Major GC(因为Major GC一般伴随着Minor GC,也可以看做触发了Full GC)。老年代的内存空间远大于新生代,进行一次Full GC消耗的时...原创 2020-04-20 16:52:50 · 27245 阅读 · 2 评论 -
JVM内存模型和性能调优:JVM内存参数设置- 第19篇
前言 在前面我们讲了堆内存中牵涉的几块区域,那么这几块区域是否可以设置大小呐? 答案肯定是可以的。一、JVM内存参数设置(1)Xss :含义:设置线程栈大小,默认值为1M;辅助记忆:ss -> stack size -X:非标准参数。这些参数不是虚拟机规范规定的。因此,不是所有VM的实现(如:HotSpot,JRockit,...原创 2020-04-20 16:53:35 · 27968 阅读 · 0 评论 -
JVM内存模型和性能调优:JVM的运行模式和逃逸分析- 第20篇
一、运行模式JVM的运行模式有三种:(1)解释模式(Interpreted Mode):使用解释器(-Xint 强制JVM使用解释模式),执行一行JVM字节码就编译一行为机器码(0101)。 特点:启动快,执行整体慢。(2)编译模式(Compiled Mode):使用编译器(-Xcomp JVM使用编译模式),先将所有JVM字节码一次编译为机器码,然后一次性执行所有...原创 2020-04-20 16:54:33 · 27515 阅读 · 0 评论 -
JVM内存模型和性能调优:JVM内存模型整体回顾- 第21篇
对于原先本章第一节的那张图片,带领和大家一起回顾下:整体:(1)类加载子系统:就是上面我们讲过的类加载器做的事情。(2)字节码执行引擎:顾名思义就是执行字节码指令的。(3)运行时数据区:Java虚拟机在执行Java程序过程中会把内存区域划分为若干个不同的数据区域,这些区域统称为运行时数据区。(4)栈(线程):栈是运行时单位,栈是线程私有的,所以称为线程栈。栈(Stac...原创 2020-04-20 16:58:53 · 27107 阅读 · 0 评论 -
JVM内存模型和性能调优:JVM内存分配与回收:对象优先在Eden区分配- 第22篇
大多数情况下,对象在新生代中 Eden 区分配。当 Eden 区没有足够空间进行分配时,虚拟机将发起一次Minor GC。我们来进行实际测试一下,在测试之前我们先来看看 Minor GC和Full GC 有什么不同呢?Minor GC/Young GC:指发生新生代的的垃圾收集动作,Minor GC非常频繁,回收速度一般也比较快。 Major GC/Full GC:一般会回收老年代 ,年...原创 2020-04-23 15:49:16 · 27693 阅读 · 0 评论 -
JVM内存模型和性能调优:JVM内存分配与回收:大对象直接进入老年代- 第23篇
一、大对象直接进入老年代1.1 定义大对象就是需要大量连续内存空间的对象(比如:字符串、数组)。JVM参数 -XX:PretenureSizeThreshold 可以设置大对象的大小,如果对象超过设置大小会直接进入老年代,不会进入年轻代,这个参数只在 Serial (串行收集器)和ParNew(Serial收集器的多线程版本)两个收集器下有效。1.2 演示设置JVM参数:-X...原创 2020-04-23 15:52:01 · 28385 阅读 · 0 评论 -
JVM内存模型和性能调优:JVM内存分配与回收:长期存活的对象将进入老年代- 第24篇
一、长期存活的对象将进入老年代 既然虚拟机采用了分代收集的思想来管理内存,那么内存回收时就必须能识别哪些对象应放在新生代,哪些对象应放在老年代中。为了做到这一点,虚拟机给每个对象一个对象年龄(Age)计数器。如果对象在 Eden 出生并经过第一次 Minor GC 后仍然能够存活,并且能被 Survivor 容纳的话,将被移动到 Survivor 空间中,并将对象年龄设为1。对...原创 2020-04-24 11:17:45 · 27515 阅读 · 0 评论 -
JVM内存模型和性能调优:JVM内存分配与回收:对象动态年龄判断- 第25篇
一、对象动态年龄判断当前放对象的Survivor区域里(其中一块区域,放对象的那块S区),一批对象的总大小大于这块Survivor区域内存大小的50%(-XX:TargetSurvivorRatio可以指定),那么此时大于等于这批对象年龄最大值的对象,就可以直接进入老年代了。例如Survivor区域里现在有一批对象,年龄1+年龄2+年龄n的多个年龄对象总和超过了Survivor区域的50%...原创 2020-04-24 11:18:46 · 27903 阅读 · 0 评论 -
JVM内存模型和性能调优:JVM内存分配与回收:Minor GC后存活的对象Survivor区放不下- 第26篇
Minor GC后存活的对象Survivor区放不下,这种情况会把存活的对象部分挪到老年代,部分可能还会放在Survivor区。(1)当我们的代码中有allocation1和allocation2byte[] allocation1;allocation1 = new byte[60*1024*1024];//60M//-- allocation1 + allocation2 su...原创 2020-04-24 11:20:19 · 28561 阅读 · 0 评论 -
JVM内存模型和性能调优:JVM内存分配与回收:老年代空间分配担保机制- 第27篇
年轻代每次minor GC之前JVM都会计算下老年代剩余可用空间如果这个可用空间小于年轻代里现有的所有对象大小之和( 包括垃圾对象 )就会看一下“-XX:-HandlePromotionFailure”( jdk1.8默认就设置了 )的参数是否设置了。如果有这个参数,就会看看老年代的可用内存大小,是否大于之前每一次minor GC后进入老年代的对象的平均大小。如果上一步结果是小于或...原创 2020-04-24 11:21:47 · 27810 阅读 · 0 评论 -
JVM内存模型和性能调优:垃圾收集算法:如何判断对象可以被回收(第一篇)- 第28篇
堆中几乎放着所有的对象实例,对堆垃圾回收前的第一步就是要判断哪些对象已经死亡(即不能再被任何途径使用的对象)一、引用计数法 给对象中添加一个引用计数器,每当有一个地方引用它,计数器就加1;当引用失效,计数器就减1;任何时候计数器为0的对象就是不可能再被使用的。这个方法实现简单,效率高,但是目前主流的虚拟机中并没有选择这个算法来管理内存,其最主要的原因是...原创 2020-04-26 13:50:24 · 27235 阅读 · 0 评论 -
JVM内存模型和性能调优:垃圾收集算法:如何判断对象可以被回收(第二篇)- 第29篇
四、finalize()方法最终判定对象是否存活 即使在可达性分析算法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段,要真正宣告一个对象死亡,至少要经历再次标记过程。标记的前提是对象在进行可达性分析后发现没有与GC Roots相连接的引用链。(1)第一次标记并进行一次筛选。 筛选的条件是此对象是否有必要执行finalize()...原创 2020-04-26 13:52:47 · 27547 阅读 · 0 评论 -
JVM内存模型和性能调优:垃圾收集算法:垃圾收集算法 - 第30篇
一、标记-清除算法算法分为“标记”和“清除”阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。标记-清除算法最基础的收集算法,效率也很高,但是会带来两个明显的问题:(1)效率问题 : 相对于复制算法而言。(2)空间问题(标记清除后会产生大量不连续的碎片):大对象就不能进行保存了。二、复制算法为了解决效率问题,“复制”收...原创 2020-04-26 13:54:14 · 27552 阅读 · 0 评论 -
JVM内存模型和性能调优:垃圾收集算法:垃圾收集器(一) - 第31篇
如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现。垃圾收集器就是垃圾收集算法的具体实现。 虽然我们对各个收集器进行比较,但并非为了挑选出一个最好的收集器。因为直到现在为止还没有最好的垃圾收集器出现,更加没有万能的垃圾收集器,我们能做的就是根据具体应用场景选择适合自己的垃圾收集器。试想一下:如果有一种四海之内、任何场景下都适用...原创 2020-04-26 13:55:31 · 27659 阅读 · 1 评论 -
JVM内存模型和性能调优:垃圾收集算法:垃圾收集器(二) - 第32篇
四、CMS收集器(-XX:+UseConcMarkSweepGC『old:只能用在老年代 』)CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。它非常符合在注重用户体验的应用上使用,它是HotSpot虚拟机第一款真正意义上的并发收集器,它第一次实现了让垃圾收集线程与用户线程(基本上)同时工作。从名字中的Mark Sweep这两个词可以看出...原创 2020-04-28 13:57:54 · 27177 阅读 · 0 评论 -
JVM内存模型和性能调优:垃圾收集算法:垃圾收集器(三) - 第33篇
五、G1收集器(-XX:+UseG1GC)5.1 概念G1 (Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多核处理器及大容量内存的机器. 以极高概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征(面对大容量内存的机器)。 G1将Java堆划分为多个大小相等的独立区域(Region),JVM最多可以有2048个Region。...原创 2020-04-28 13:59:09 · 27209 阅读 · 0 评论 -
JVM内存模型和性能调优:垃圾收集算法:每秒几十万并发的系统优化JVM - 第34篇
一、每秒几十万并发的系统优化JVMKafka类似的支撑高并发消息系统大家肯定不陌生,对于Kafka来说,每秒处理几万甚至几十万消息时很正常的。一般来说部署Kafka需要用大内存机器( 比如64G ),也就是说可以给年轻代分配个三四十G的内存用来支撑高并发处理。这里就涉及到一个问题了,我们以前常说的对于Eden区的young GC是很快的,这种情况下它的执行还会很快吗?很显然,不可能...原创 2020-04-28 13:59:58 · 27986 阅读 · 0 评论 -
JVM内存模型和性能调优:垃圾收集算法:亿级流量电商系统如何优化JVM参数 - 第35篇
亿级流量电商系统如何优化JVM参数设置:ParNew+CMS大型电商系统后端现在一般都是拆分为多个子系统部署的,比如,商品系统,库存系统,订单系统,促销系统,会员系统等等。占用字节表:我们这里以比较核心的订单系统为例:对于8G内存,我们一般是分配4G内存给JVM,正常的JVM参数配置如下:-Xms3072M -Xmx3072M -Xmn1536M -Xss1M ...原创 2020-04-28 14:02:22 · 27795 阅读 · 0 评论 -
JVM内存模型和性能调优:JVM调优工具详解及调优实战:Jmap - 第36篇
此命令可以用来查看内存信息。一、实例个数以及占用内存大小命令:jmap -histo 91289 > /data/tmp/log.txt其中91289是进程ID,使用jps进行查看。打开log.txt,文件内容如下(HeapTest):num:序号 instances:实例数量 bytes:占用空间大小 class name:类名称,[C is a ch...原创 2020-04-28 14:05:25 · 27637 阅读 · 0 评论 -
JVM内存模型和性能调优:JVM调优工具详解及调优实战:Jstack - 第37篇
查看线程一、用jstack加进程id查找死锁 用jstack加进程id查找死锁,见如下示例DeadLockTest:public class DeadLockTest { private static Object lock1 = new Object(); private static Object lock2 = new Object(); ...原创 2020-05-07 13:57:52 · 27060 阅读 · 0 评论 -
JVM内存模型和性能调优:JVM调优工具详解及调优实战:jstat - 第38篇
一、说明jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:jstat [-命令选项] [vmid] [间隔时间(毫秒)] [查询次数]注意:使用的jdk版本是jdk8.二、垃圾回收统计最常用,可以评估程序内存使用及GC压力整体情况。指令:jstat -gc pid指令:jstat -gc pid [interval] [...原创 2020-05-07 14:00:43 · 27404 阅读 · 0 评论