史上最全JVM知识点梳理
2021-06-03 17:37:00   0  举报             
     
         
 AI智能生成
  整理的康师傅老师的JVM课程笔记,希望能帮助您~
    作者其他创作
 大纲/内容
  https://docs.oracle.com/javase/8/  
     https://www.processon.com/view/link/606d1f9d7d9c0829db732d26#map  
     01_内存与垃圾回收篇    
     01_JVM与Java体系结构  
     02_类加载子系统  
     03_运行时数据区概述及线程  
     04_程序计数器  
     05_虚拟机栈  
     06_本地方法接口  
     07_本地方法栈  
     08_堆  
     09_方法区  
     10_对象的实例化内存布局与访问定位  
     11_直接内存  
     12_执行引擎  
     13_StringTable  
     14_垃圾回收概述  
     15_垃圾回收相关算法  
     16_垃圾回收相关概念  
     17_垃圾回收器    
     怎么选择垃圾回收器?    
     优化调整堆的大小让JVM自适应完成  
     如果内存小于100M,使用串行收集器  
     如果是单核、单机程序,并且没有停顿时间的要求,使用串行收集器  
     如果是多CPU、需要高吞吐量、允许停顿时间超过1秒,选择并行或者JVM自己选择  
     如果是多CPU、追求低停顿时间,需快速响应(比如延迟不能超过1秒,如互联网应用),使用并发收集器,官方推荐G1,性能高。现在互联网的项目,基本都是使用G1。  
     最后需要明确一个观点:    
     没有最好的收集器,更没有万能的收集器  
     调优永远是针对特定场景、特定需求,不存在一劳永逸的收集器  
     GC日志分析    
     -verbose:gc    
     这个只会显示总的GC堆的变化  
     参数解析    
     GC、Full GC:GC的类型,GC只在新生代上进行,Full GC包括新生代、老年代、永久代  
     Allocation Failure:GC发生的原因  
     80832k->19298k:堆在GC前的大小和GC后的大小  
     227840k:现在堆的大小  
     0.0084018 secs:GC持续的时间  
     -verbose:gc -XX:+PrintGCDetails    
     输入信息  
     参数解析  
     -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps    
     带上了日期和时间  
     日志补充说明           
     年轻代 GC  
     老年代 GC  
     GC日志分析工具  
     02_字节码与类的加载篇    
     Class文件结构           
     01_概述    
     字节码文件的跨平台性           
     Java的前端编译器  
     透过字节码指令看代码细节  
     02_虚拟机的基石:Class文件    
     操作码 (操作数)  
     方式一  
     方式三  
     03_Class文件结构    
     01-魔数:Class文件的标志  
     02-Class文件版本号  
     03-常量池:存放所有常量    
     1-常量池计数器  
     2-常量池表    
     2.1 字面量和符号引用                         
     2.2 常量类型和结构                  
     04-访问标识           
     05-类索引、父类索引、接口索引集合  
     06-字段表集合    
     1-字段计数器  
     2-字段表                  
     07-方法表集合    
     1-方法计数器  
     2-方法表           
     08-属性表集合    
     1-属性计数器  
     2-属性表           
     小结  
     04_使用javap指令解析Class文件    
     1-解析字节码的作用  
     2- javac -g操作  
     3- javap的用法  
     4-使用举例  
     5-总结  
     字节码指令集与解析举例    
     01-概述    
     执行模型  
     字节码与数据类型  
     指令分类  
     02-加载与存储指令    
     复习:再谈操作数栈与局部变量表    
     操作数栈  
     局部变量表           
     1-局部变量压栈指令  
     2-常量入栈指令    
     指令push系列  
     指令ldc系列  
     指令const系列  
     3-出栈装入局部变量表指令           
     03-算术指令    
     所有算术指令  
     比较指令的说明  
     04-类型转换指令    
     1-宽化类型转换  
     2-窄化类型转换  
     05-对象的创建与访问指令    
     1-创建指令  
     2-字段访问指令  
     3-数组操作指令  
     4-类型检查指令  
     06-方法调用与返回指令    
     1-方法调用指令           
     2-方法返回指令  
     07-操作数栈管理指令  
     08-控制转移指令    
     1-条件跳转指令  
     2-比较条件跳转指令  
     3-多条件分支指令  
     4-无条件跳转  
     09-异常处理指令    
     1-抛出异常指令  
     2-异常处理与异常表  
     10-同步控制指令    
     1-方法级的同步  
     2-方法内指定指令序列的同步  
     类的加载过程(类的生命周期)详解    
     01-概述    
     类的使用过程  
     大厂面试题  
     02-过程一:Loading(加载)阶段    
     1-加载完成的操作  
     2-二进制流的获取方式  
     3-类模型与Class实例的位置  
     4-数组类的加载  
     03-过程二:Linking(链接)阶段    
     1-环节1:链接阶段之Verification(验证)  
     2-环节2:链接阶段之Preparation(准备)  
     3-环节3:链接阶段之Resolution(解析)  
     04-过程三:Initialization(初始化)阶段    
     1-static与final的搭配问题  
     2-<clinit>()的线程安全性  
     3-类的初始化情况:主动使用vs被动使用    
     -XX:+TraceClassLoading  
     05-过程四:类的Using(使用)  
     06-过程五:类的Unloading(卸载)    
     回顾:方法区的垃圾回收  
     再谈类的加载器    
     01-概述    
     1-大厂面试题  
     2-类加载的分类  
     3-类加载器的必要性  
     4-命名空间  
     5-类加载机制的基本特征  
     02-复习:类的加载器分类    
     1-引导类加载器  
     2-扩展类加载器  
     3-系统类加载器  
     4-用户自定义类加载器  
     03-测试不同的类加载器  
     04-ClassLoader源码解析    
     ClassLoader的主要方法  
     SecureClassLoader与URLClassLoader  
     ExtClassLoader与AppClassLoader  
     Class.forName()与ClassLoader.loadClass()  
     05-双亲委派模型    
     定义与本质  
     优势与劣势  
     破坏双亲委派机制    
     破坏双亲委派机制1  
     破坏双亲委派机制2  
     破坏双亲委派机制3  
     热替换的实现  
     06-沙箱安全机制    
     JDK1.0时期  
     JDK1.1时期  
     JDK1.2时期  
     JDK1.6时期  
     07-自定义类的加载器    
     实现方式  
     08-Java9新特性    
     双亲委派模型改变  
     03_性能监控与调优篇    
     概述篇    
     1-大厂面试题  
     2-背景说明    
     1-生产环境中的问题    
     生产环境发生了内存溢出该如何处理?  
     生产环境应该给服务器分配多少内存合适?  
     如何对垃圾回收器的性能进行调优?  
     生产环境CPU负载飙高该如何处理?  
     生产环境应该给应用分配多少线程合适?  
     不加log,如何确定请求是否执行了某一行代码?  
     不加log,如何实时查看某个方法的入参与返回值?  
     2-为什么要调优?    
     防止出现OOM  
     解决OOM  
     减少Full GC出现的频率  
     3-不同阶段的考虑    
     上线前  
     项目运行阶段  
     线上出现OOM  
     3-调优概述    
     1-监控的依据    
     运行日志  
     异常堆栈
  
     GC日志  
     线程快照  
     堆转储快照  
     2-调优的大方向    
     合理地编写代码  
     充分并合理的使用硬件资源  
     合理地进行JVM调优  
     4-性能优化的步骤    
     第1步(发现问题):性能监控    
     GC 频繁  
     cpu load 过高
  
     OOM  
     内存泄漏  
     死锁  
     程序响应时间较长  
     第2步(排查问题):性能分析    
     打印GC日志,通过GCviewer或者http://gceasy.io来分析日志信息  
     灵活运用命令行工具,jstack、jmap、jinfo等  
     dump出堆文件,使用内存分析工具分析文件  
     使用阿里Arthas,或jconsole,JVisualVM来实时查看JVM状态  
     jstack查看堆栈信息  
     第3步(解决问题):性能调优    
     适当增加内存,根据业务背景选择垃圾回收器  
     优化代码,控制内存使用  
     增加机器,分散节点压力  
     合理设置线程池线程数量  
     使用中间件提高程序效率,比如缓存,消息队列等  
     其他......  
     5-性能评价/测试指标    
     1-停顿时间(或响应时间)    
     -XX:MaxGCPauseMillis  
     2-吞吐量    
     对单位时间内完成的工作量(请求)的量度  
     在GC中:运行用户代码的时间占总运行时间的比例(总运行时间:程序的运行时间 + 内存回收的时间)
吞吐量为 1 - 1/(1+n)。-XX:GCTimeRatio=n
    吞吐量为 1 - 1/(1+n)。-XX:GCTimeRatio=n
 3-并发数    
     同一时刻,对服务器有实际交互的请求数  
     4-内存占用    
     Java堆区所占的内存大小  
     5-相互间的关系    
     以高速公路通行状况为例  
     JVM监控及诊断工具-命令行篇    
     01-概述    
     简单命令行工具  
     02-jps:查看正在运行的Java进程    
     基本情况  
     测试  
     基本语法    
     options参数  
     hostid参数  
     03-jstat:查看JVM统计信息    
     基本情况  
     基本语法    
     option参数    
     -gc    
     新生代相关    
     S0C是第一个幸存者区的大小(字节)  
     S1C是第二个幸存者区的大小(字节)  
     S0U是第一个幸存者区已使用的大小(字节)  
     S1U是第二个幸存者区已使用的大小(字节)  
     EC是Eden空间的大小(字节)  
     EU是Eden空间已使用的大小(字节)  
     老年代相关
    
     OC是老年代的大小(字节)  
     OU是老年代已使用的大小(字节)  
     方法区(元空间)相关    
     MC是方法区的大小  
     MU是方法区已使用的大小  
     CCSC是压缩类空间的大小  
     CCSU是压缩类空间已使用的大小  
     其它    
     YGC是指从应用程序启动到采样时young gc次数  
     YGCT是指从应用程序启动到采样时young gc消耗的时间(秒)  
     FGC是指从应用程序启动到采样时full gc次数  
     FGCT是指从应用程序启动到采样时full gc消耗的时间(秒)  
     GCT是指从应用程序启动到采样时gc的总时间  
     interval参数    
     用于指定输出统计数据的周期,单位为毫秒。即查询间隔  
     count参数    
     用于指定查询的总次数  
     -t参数    
     可以在输出信息前加上一个Timestamp列,显示程序的运行时间。单位:秒  
     经验  
     -h参数    
     可以在周期性数据输出时,输出多少行数  
     补充  
     04-jinfo:实时查看和修改JVM配置参数    
     基本情况  
     基本语法    
     查看    
     jinfo -sysprops PID    
     可以查看由System.getProperties()取得的参数  
     jinfo -flags PID    
     查看曾经赋过值得一些参数  
     jinfo -flag 具体参数 PID    
     查看某个Java进程的具体参数的值  
     修改    
     针对boolean类型    
     jinfo -flag [+|-]具体参数 PID  
     针对非boolean类型    
     jinfo -flag 具体参数=具体参数值 PID  
     扩展    
     java -XX:+PrintFlagsInitial    
     查看所有JVM参数启动的初始值  
      java -XX:+PrintFlagsFinal    
     查看所有JVM参数的最终值  
     java -XX:+PrintCommandLineFlags    
     查看那些已经被用户或者JVM设置过的详细的XX参数的名称和值  
     05-jmap:导出内存映射文件&内存使用情况    
     基本情况  
     基本语法    
     -dump    
     生成Java堆转储快照:dump文件  
     特别的:-dump:live只保存堆中的存活对象  
     -heap    
     输出整个堆空间的详细信息,包括GC的使用、堆配置信息,以及内存的使用  
     -histo    
     输出堆中对象的统计信息,包括类、实例数量和合计容量  
     特别的:-histo:live只统计堆中的存活对象  
     -permstat    
     以ClassLoader为统计口径输出永久代的内存状态信息  
     仅linux/solaris平台有效  
     -finalizerinfo    
     显示在F-Queue中等待Finalizer线程执行finalize方法的对象  
     仅linux/solaris平台有效  
     -F    
     当虚拟机进程对-dump选项没有任何响应时,可使用此选项强制执行生成  
     仅linux/solaris平台有效  
     -h | -help    
     jmap工具使用的帮助命令  
     -J <flag>    
     传递参数给jmap启动的jvm  
     使用1:导出内存映像文件    
     手动的方式    
     jmap -dump:format=b,file=<filename.hprof> <pid>  
     jmap -dump:live,format=b,file=<filename.hprof> <pid>  
     自动的方式    
     -XX:+HeapDumpOnOutOfMemoryError  
     -XX:HeapDumpPath=<filename.hprof>  
     使用2:显示堆内存相关信息    
     jmap -heap pid  
     jmap -histo  
     使用3:其它作用    
     jmap -permstat pid    
     查看系统的ClassLoader信息  
     jmap -finalizerinfo    
     查看堆积在finalizer队列中的对象  
     小结  
     06-jhat:JDK自带堆分析工具    
     基本情况  
     基本语法    
     option参数:-stack false|true    
     关闭|打开对象分配调用栈跟踪  
     option参数:-refs false|true    
     关闭|打开对象应用跟踪  
     option参数:-port port-number    
     设置jhat HTTP Server的端口号,默认7000  
     option参数:-exclude exclude-file    
     执行对象查询时需要排除的数据成员  
     option参数:-baseline exclude-file    
     指定一个基准堆转储  
     option参数:-debug int    
     设置debug级别  
     option参数:-version    
     启动后显示版本信息就退出  
     option参数:-J<flag>    
     传入启动参数,比如-J -Xmx512m  
     07-jstack:打印JVM中线程快照    
     基本情况  
     基本语法    
     option参数:-F    
     当正常输出的请求不被响应时,强制输出线程堆栈  
     option参数:-l    
     除堆栈外,显示关于所的附加信息  
     option参数:-m    
     如果调用到本地方法的话,可以显示C/C++的堆栈  
     option参数:-h    
     帮助操作  
     08-jcmd:多功能命令行    
     基本使用  
     基本语法    
     jcmd -l    
     列出所有的JVM进程  
     jcmd pid help    
     针对指定的进程,列出支持的所有命令  
     jcmd pid 具体命令    
     显示指定进程的指令命令的数据  
     09-jstatd:远程主机信息收集  
     JVM监控及诊断工具-GUI篇    
     01-工具概述  
     02-jConsole    
     基本概念  
     启动    
     jdk/bin目录下,启动jconsole.exe命令即可  
     不需要使用jps命令来查询  
     三种连接方式    
     Local    
     使用JConsole连接一个正在本地系统运行的JVM,并且执行程序的和运行JConsole的需要是同一个用户。
JConsole使用文件系统的授权通过RMI连接器连接到平台的MBean服务器上。这种从本地连接的监控能力只有Sun的JDK具有。
    JConsole使用文件系统的授权通过RMI连接器连接到平台的MBean服务器上。这种从本地连接的监控能力只有Sun的JDK具有。
 Remote    
     使用下面的URL通过RMI连接器连接到一个JMX代理,service:jmx:rmi:///jndi/rmi://hostName:portNum/jmxrmi。
JConsole为建立连接,需要在环境变量中设置mx.remote.credentials来指定用户名和密码,从而进行授权。
    JConsole为建立连接,需要在环境变量中设置mx.remote.credentials来指定用户名和密码,从而进行授权。
 Advanced    
     使用一个特殊的URL连接JMX代理。一般情况使用自己定制的连接器而不是RMI提供的连接器来连接JMX代理,或者是一个使用JDK1.4的实现了JMX和JMX Remote的应用。  
     主要作用  
     03-Visual VM    
     基本概念  
     插件的安装  
     连接方式    
     本地连接    
     监控本地Java进程的CPU、类、线程等  
     远程连接    
     1-确定远程服务器的IP地址  
     2-添加JMX(通过JMX技术具体监控远端服务器哪个Java进程)  
     3-修改bin/catalina.sh文件,远程连接的Tomcat  
     4-在.../conf中添加jmxremote.access和jmxremote.password文件  
     5-将服务器地址改为公网IP地址  
     6-设置阿里云安全策略和防火墙策略  
     7-启动Tomcat,查看Tomcat启动日志和端口监听  
     8-JMX中输入端口号、用户名、密码登录  
     主要功能    
     1-生成/读取堆内存快照  
     2-查看JVM参数和系统属性  
     3-查看运行中的虚拟机进程  
     4-生成/读取线程快照  
     5-程序资源的实时监控  
     6-其他功能    
     JMX代理连接  
     远程环境监控  
     CPU分析和内存分析  
     04-eclipse MAT    
     基本概述  
     获取堆dump文件    
     dump文件内容  
     两点说明  
     获取dump文件  
     分析堆dump文件    
     histogram    
     展示了各个类的实例数目以及这些实例的Shallow heap或 Retainedheap的总和  
     thread overview    
     查看系统中的Java线程  
     查看局部变量的信息  
     获得对象相互引用的关系    
      with outgoing references  
     with incoming references  
     浅堆与深堆    
     shallow heap  
     retained heap  
     补充:对象实际大小  
     练习    
     图一  
     图二  
     案例分析:StudentTrace  
     支配树  
     案例:Tomcat堆溢出分析    
     说明  
     分析过程    
     图1  
     图2  
     图3  
     图4  
     图5  
     图6  
     图7  
     图8  
     补充1:再谈内存泄漏    
     内存泄漏的理解与分类    
     内存泄漏  
     Java中内存泄漏的8种情况    
     1-静态集合类  
     2-单例模式  
     3-内部类持有外部类  
     4-各种连接,如数据库连接、网络连接和IO连接等  
     5-变量不合理的作用域  
     6-改变哈希值  
     7-缓存泄漏  
     8-监听器和回调  
     内存泄漏案例分析    
     案例    
     案例代码  
     分析    
     图一  
     图二  
     解决办法  
     补充2:支持使用OQL语言查询对象信息    
     SELECT子句  
     FROM子句  
     WHERE子句  
     内置对象与方法  
     05-JProfiler    
     基本概述    
     介绍  
     特点  
     主要功能    
     1-方法调用    
     对方法调用的分析可以帮助您了解应用程序正在做什么,并找到提高其性能的方法  
     2-内存分配    
     通过分析堆上对象、引用链和垃圾收集能帮您修复内存泄漏问题,优化内存使用  
     3-线程和锁    
     JProfiler提供多种针对线程和锁的分析视图助您发现多线程问题  
     4-高级子系统    
     许多性能问题都发生在更高的语义级别上。例如,对于JDBC调用,您可能希望找出执行最慢的SQL语句。JProfiler支持对这些子系统进行集成分析  
     安装与配置    
     下载与安装  
     JProfiler中配置IDEA  
     IDEA集成JProfiler  
     具体使用    
     数据采集方式    
     Instrumentation重构模式  
     Sampling抽样模式  
     遥感监测 Telemetries  
     内存视图 Live Memory  
     堆遍历 heap walker  
     cpu视图 cpu views  
     线程视图 threads  
     监视器&锁 Monitors&locks  
     案例分析    
     案例1  
     06-Arthas    
     基本概述    
     背景  
     概述  
     基于哪些工具开发而来  
     官方使用文档    
     https://arthas.aliyun.com/zh-cn/  
     安装与使用    
     安装  
     工程目录  
     启动  
     查看进程  
     查看日志    
     cat ~/logs/arthas/arthas.log  
     参看帮助    
     java -jar arthas-boot.jar -h  
     web console  
     退出  
     相关诊断指令    
     基础指令  
     jvm相关    
     dashboard  
     thread  
     jvm  
     其它  
     class/classloader相关    
     sc  
     sm  
     jad  
     mc、redefine  
     classloader  
     monitor/watch/trace相关    
     monitor  
     watch  
     trace  
     stack  
     tt  
     其它    
     profiler/火焰图  
     options  
     07-Java Mission Control    
     历史  
     启动  
     概述  
     功能:实时监控JVM运行时的状态  
     Java Flight Recorder  
     08-其它工具    
     Flame Graphs(火焰图)  
     Tprofiler  
     Btrace  
     YourKit  
     JProbe  
     Spring Insight  
     JVM运行时参数    
     01-JVM参数选项类型    
     类型一:标准参数选项    
     特点    
     比较稳定,后续版本基本不会变化  
     以-开头  
     各种选项    
     运行java或者java -help可以看到所有的标准选项  
     补充内容:-server与-client  
     类型二:-X参数选项    
     特点    
     非标准化参数  
     功能还是比较稳定的。但官方说后续版本可能会变更  
     以-X开头  
     各种选项    
     运行java -X命令可以看到所有的X选项  
     JVM的JIT编译模式相关的选项    
     -Xint    
     禁用JIT,所有字节码都被解释执行,这个模式的速度最慢的  
     -Xcomp    
     所有字节码第一次使用就都被编译成本地代码,然后再执行  
     -Xmixed    
     混合模式,默认模式,让JIT根据程序运行的情况,有选择地将某些代码编译进行缓存起来  
     特别地    
     -Xmx -Xms -Xss属于 XX 参数?    
     -Xms<size>    
     设置初始Java堆大小,等价于-XX:InitialHeapSize  
     -Xmx<size>    
     设置最大Java堆大小,等价于-XX:MaxHeapSize  
     -Xss<size>    
     设置Java线程堆栈大小,-XX:ThreadStackSize  
     类型三:-XX参数选项    
     特点    
     非标准化参数  
     使用的最多的参数类型  
     这类选项属于实验性,不稳定  
     以-XX开头  
     作用    
     用于开发和调试JVM  
     分类    
     Boolean类型格式    
     -XX:+<option>表示启用option属性  
     -XX:-<option>表示禁用option属性  
     举例  
     说明:因为有的指令默认是开启的,所以可以使用-关闭  
     非Boolean类型格式(key-value类型)    
     子类型1:数值型格式-XX:<option>=<number>  
     子类型2:非数值型格式-XX:<name>=<string>  
     特别地    
     -XX:+PrintFlagsFinal    
     输出所有参数的名称和默认值  
     默认不包括Diagnostic和Experimental的参数  
     可以配合-XX:+UnlockDiagnosticVMOptions和-XX:UnlockExperimentalVMOptions使用  
     02-添加JVM参数选项    
     Eclipse  
     IDEA  
     运行jar包    
     java -Xms50m -Xmx50m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -jar demo.jar  
     通过Tomcat运行war包    
     Linux系统下可以在tomcat/bin/catalina.sh中添加类似如下配置:
JAVA_OPTS="-Xms512M -Xmx1024M"
    JAVA_OPTS="-Xms512M -Xmx1024M"
 Windows系统下在catalina.bat中添加类似如下配置:
set "JAVA_OPTS=-Xms512M -Xmx1024M"
    set "JAVA_OPTS=-Xms512M -Xmx1024M"
 程序运行过程中    
     使用jinfo -flag <name>=<value> <pid> 设置非Boolean类型参数  
     使用jinfo -flag [+|-]<name> <pid> 设置Boolean类型参数  
     03-常用的JVM参数选项    
     打印设置的XX选项及值    
     -XX:+PrintCommandLineFlags    
     可以让程序运行前打印出用户手动设置或者JVM自动设置的XX选项  
     -XX:+PrintFlagsInitial    
     表示打印出所有XX选项的默认值  
     -XX:+PrintFlagsFinal    
     表示打印出XX选项在运行程序时生效的值  
     -XX:+PrintVMOptions    
     打印JVM的参数  
     堆、栈、方法区等内存大小设置    
     栈    
     -Xss128k    
     设置每个线程的栈大小为128k  
     等价于 -XX:ThreadStackSize=128k  
     堆内存    
     -Xms3550m    
     等价于-XX:InitialHeapSize,设置JVM初始堆内存为3550M  
     -Xmx3550m    
     等价于-XX:MaxHeapSize,设置JVM最大堆内存为3550M  
     -Xmn2g    
     设置年轻代大小为2G  
     官方推荐配置为整个堆大小的3/8  
     -XX:NewSize=1024m    
     设置年轻代初始值为1024M  
     -XX:MaxNewSize=1024m    
     设置年轻代最大值为1024M  
     -XX:SurvivorRatio=8    
     设置年轻代中Eden区与Survivor区的比值,默认为8  
     -XX:UseAdaptiveSizePolicy    
     自动选择各区大小比例  
     -XX:NewRatio=2    
     设置老年代与年轻代(包括1个Eden和2个Survivor区)的比值  
     -XX:PretenureSizeThreadshold=1024    
     设置让大于此阈值的对象直接分配在老年代,单位为字节  
     只对Serial、ParNew收集器有效  
     -XX:MaxTenuringThreshold=15    
     默认值15  
     新生代每次MinorGC后,还存活的对象年龄+1,当对象的年龄大于设置的这个值时就进入老年代  
     -XX:+PrintTenuringDistribution    
     让JVM在每次MinorGC后打印出当前使用的Survivor中对象的年龄分布  
     -XX:TargetSurvivorRatio    
     表示MinorGC结束后Survivor区域中占用空间的期望比例  
     方法区    
     永久代    
     -XX:PermSize=256m    
     设置永久代初始值为256M  
     -XX:MaxPermSize=256m    
     设置永久代最大值为256M  
     元空间    
     -XX:MetaspaceSize    
     初始空间大小  
     -XX:MaxMetaspaceSize    
     最大空间,默认没有限制  
     -XX:+UseCompressedOops    
     压缩对象指针  
     -XX:+UseCompressedClassPointers    
     压缩类指针  
     -XX:CompressedClassSpaceSize    
     设置Klass Metaspace的大小,默认1G  
     直接内存    
     -XX:MaxDirectMemorySize    
     指定DirectMemory容量,若未指定,则默认与Java堆最大值一样  
     OutOfMemory相关的选项    
     -XX:+HeapDumpOnOutOfMemoryError    
     表示在内存出现OOM的时候,把Heap转存(Dump)到文件以便后续分析  
     -XX:+HeapDumpBeforeFullGC    
     表示在出现FullGC之前,生成Heap转储文件  
     -XX:HeapDumpPath=<path>    
     指定heap转存文件的存储路径  
     -XX:OnOutOfMemoryError    
     指定一个可行性程序或者脚本的路径,当发生OOM的时候,去执行这个脚本  
     垃圾收集器相关选项    
     7款经典收集器与垃圾分代之间的关系  
     垃圾收集器的组合关系  
     查看默认垃圾回收器  
     Serial回收器  
     ParNew回收器  
     Paraller回收器  
     CMS回收器    
     补充参数  
     特别说明  
     G1回收器    
     Mixed GC调优参数  
     怎么选择垃圾回收器  
     GC日志相关选项    
     常用参数    
     -verbose:gc    
     输出gc日志信息,默认输出到标准输出  
     可以独立使用  
     -XX:+PrintGC    
     等同于-verbose:gc
表示打开简化的GC日志
    表示打开简化的GC日志
 可以独立使用  
     -XX:+PrintGCDetails    
     在发生垃圾回收时打印内存回收详细的日志,
并在进程退出时输出当前内存各区域分配情况
    并在进程退出时输出当前内存各区域分配情况
 可以独立使用  
     -XX:+PrintGCTimeStamps    
     输出GC发生时的时间戳  
     不可以独立使用,需要配合-XX:+PrintGCDetails使用  
     -XX:+PrintGCDateStamps    
     输出GC发生时的时间戳(以日期的形式,如2013-05-04T21:53:59.234+0800)  
     不可以独立使用,需要配合-XX:+PrintGCDetails使用  
     -XX:+PrintHeapAtGC    
     每一次GC前和GC后,都打印堆信息  
     可以独立使用  
     -Xloggc:<file>    
     把GC日志写入到一个文件中去,而不是打印到标准输出中  
     其他参数    
     -XX:+TraceClassLoading    
     监控类的加载  
     -XX:+PrintGCApplicationStoppedTime    
     打印GC时线程的停顿时间  
     -XX:+PrintGCApplicationConcurrentTime    
     垃圾收集之前打印出应用未中断的执行时间  
     -XX:+PrintReferenceGC    
     记录回收了多少种不同引用类型的引用  
     -XX:+PrintTenuringDistribution    
     让JVM在每次MinorGC后打印出当前使用的Survivor中对象的年龄分布  
     -XX:+UseGCLogFileRotaion    
     启动GC日志文件的自动存储  
     -XX:+NumberOfGClogFiles=1    
     GC日志文件的循环数目  
     -XX:+GCLogFileSize=1M    
     控制GC日志文件的大小  
     其他参数    
     -XX:+DisableExplicitGC    
     禁止hotspot执行System.gc(),默认禁用  
     -XX:ReservedCodeCacheSize=<n>[g|m|k]、-XX:InitialCodeCacheSize=<n>[g|m|k]    
     指定代码缓存的大小  
     -XX:+UseCodeCacheFlushing    
     使用该参数让jvm放弃一些被编译的代码,
避免代码缓存被占满时JVM切换到interpreted-only的情况
    避免代码缓存被占满时JVM切换到interpreted-only的情况
 -XX:+DoEscapeAnalysis    
     开启逃逸分析  
     -XX:+UseBiasedLocking    
     开启偏向锁  
     -XX:+UseTLAB    
     使用TLAB,默认打开  
     -XX:+PrintTLAB
    
     打印TLAB的使用情况  
     -XX:TLABSize    
     设置TLAB大小  
     04-通过Java代码获取JVM参数    
     上篇上通过Runtime获取  
     分析GC日志    
     01-GC日志参数    
     -verbose:gc    
     输出gc日志信息,默认输出到标准输出  
     -XX:+PrintGC    
     等同于-verbose:gc
表示打开简化的GC日志
    表示打开简化的GC日志
 -XX:+PrintGCDetails    
     在发生垃圾回收时打印内存回收详细的日志,
并在进程退出时输出当前内存各区域分配情况
    并在进程退出时输出当前内存各区域分配情况
 -XX:+PrintGCTimeStamps    
     输出GC发生时的时间戳  
     -XX:+PrintGCDateStamps    
     输出GC发生时的时间戳(以日期的形式,如2013-05-04T21:53:59.234+0800)  
     -XX:+PrintHeapAtGC    
     每一次GC前和GC后,都打印堆信息  
     -Xloggc:<file>    
     把GC日志写入到一个文件中去,而不是打印到标准输出中  
     02-GC日志格式    
     复习:GC分类  
     GC日志分类    
     MinorGC  
     FullGC  
     GC日志结构剖析    
     垃圾收集器  
     GC前后情况  
     GC时间  
     Minor GC 日志解析    
     2020-11-20T17:19:43.265-0800    
     日志打印事件 日期格式 如2013-05-04T21:53:59.234+0800  
     0.822    
     gc发生时,Java虚拟机启动以来经过的秒数  
     [GC (Allocation Failure)    
     发生了一次垃圾回收,这是一次Minor GC。它不区分新生代GC还是老年代GC,
括号里的内容是gc发生的原因,这里的Allocation Failure的原因是新生代中没有足够区域能存放需要分配的数据而失败。
    括号里的内容是gc发生的原因,这里的Allocation Failure的原因是新生代中没有足够区域能存放需要分配的数据而失败。
 [PSYoungGen:76800K->8433K(89600K)]    
     PSYoungGen:表示GC发生的区域,区域名称与使用的GC收集器是密切相关的    
     Serial收集器:Default New Generation显示DefNew  
     ParNew收集器:ParNew  
     Parallel Scanvenge收集器:PSYoung  
     老年代和新生代同理,也是和收集器名称相关  
     76800K->8433K(89600K):GC
前该内存区域已使用容量-> GC
后该区域容量(该区域总容量)
    前该内存区域已使用容量-> GC
后该区域容量(该区域总容量)
 如果是新生代,总容量则会显示整个新生代内存的9/10,即Eden + from/to区  
     如果是老年代总容量则是全部内存大小,无变化  
     76800K->8449K(294400K)    
     在显示完区域容量GC的情况之后,会接着显示整个堆内存区域的GC情况:GC前堆内存已使用容量 -> GC堆内存容量(堆内存总容量)
堆内存总容量 = 9/10 新生代 + 老年代 < 初始化的内存大小
    堆内存总容量 = 9/10 新生代 + 老年代 < 初始化的内存大小
 , 0.0088371 secs]    
     整个GC所花费的时间,单位是秒  
     [Times:user=0.02 sys=0.01, real=0.01 secs]    
     user:指的是CPU工作在用户态所花费的时间  
     sys:指的是CPU工作在内核态所花费的时间  
     real:指的是在此次GC事件中所花费的总时间  
     Full GC 日志剖析    
     2020-11-20T17:19:43.794-0800    
     日志打印时间 日期格式 如2013-05-04T21:53:59.234+0800  
     1.351    
     gc发生时,Java虚拟机启动以来经过的秒数  
     Full GC (Metadata GC Threshold)    
     发生了一次垃圾回收,这是一次FULL GC。它不区分新生代GC还是老年代GC  
     括号里的内容是gc发生的原因,这里的Metadata GC Threshold的原因是Metaspace区不够用了。    
     Full GC(Ergonomics):JVM自适应调整导致的GC  
     Full GC(System):调用了System.gc()方法  
     [PSYoungGen: 10082k->0k(89600k)]    
     PSYoungGen:表示GC发生的区域,区域名称与使用的GC收集器是密切相关的    
     Serial收集器:Default New Generation显示DefNew  
     ParNew收集器:ParNew  
     Parallel Scanvenge收集器:PSYoung  
     老年代和新生代同理,也是和收集器名称相关  
     10082k->0k(89600k):GC前该内存区域已使用容量 -> GC后该区域容量(该区域总容量)    
     如果是新生代,总容量则会显示整个新生代内存的9/10,即Eden + from/to区  
     如果是老年代总容量则是全部内存大小,无变化  
     [ParOldGen: 32k->9638k(204800k)]    
     老年代区域没有发生GC,因为本次GC是metaspace引起的  
     10114k->9638k(294400k)    
     在显示完区域容量GC的情况之后,会接着显示整个堆内存区域的GC情况:
GC前堆内存已使用容量 -> GC堆内存容量(堆内存总容量)
堆内存总容量 = 9/10新生代 + 老年代 < 初始化的内存大小
    GC前堆内存已使用容量 -> GC堆内存容量(堆内存总容量)
堆内存总容量 = 9/10新生代 + 老年代 < 初始化的内存大小
 [Metaspace: 20158k->20156k(1067008k)]    
     metaspace GC 回收2k空间  
     0.0285388 secs    
     整个GC所花费的时间,单位是秒  
     [Times: user=0.11, sys=0.00, real=0.03 secs]    
     user:指的是CPU工作在用户态所花费的时间  
     sys:指的是CPU工作在内核态所花费的时间  
     real:指的是在此次GC事件中所花费的总时间  
     03-GC日志分析工具    
     GCeasy    
     基本概述  
     GCViewer    
     基本概述  
     安装  
     其他工具    
     GChisto    
     官网上没有下载的地方,需要自己从SVN上拉下来来编译  
     不过这个工具似乎没怎么维护了,存在不少bug  
     HPjmeter    
     工具很强大,但只能打开由以下参数生成的GC log,-verbose:gc
-Xloggc:gc.log。添加其他参数生成的gc.log无法打开
    -Xloggc:gc.log。添加其他参数生成的gc.log无法打开
 HPjmeter集成了以前的HPjtune功能,可以分析在HP机器上产生的垃圾回收日志文件  
     OOM常见各种场景及解决方案    
     面试题  
     案例1:堆溢出    
     报错信息    
     java.lang.OutOfMemoryError:Java heap space  
     案例模拟    
     发送请求    
     http://localhost:8080/add  
     JVM参数配置  
     运行结果  
     原因及解决方案  
     dump文件分析    
     jvisualvm分析  
     MAT分析  
     gc日志文件  
     案例2:元空间溢出    
     元空间存储数据类型  
     报错信息    
     java.lang.OutOfMemoryError:Metaspace  
     案例模拟    
     示例代码  
     发送请求    
     http://localhost:8080/metaSpaceOom  
     运行结果  
     JVM参数配置  
     原因及解决方案  
     分析及解决    
     查看监控  
     查看GC状态  
     查看GC日志  
     分析dump文件    
     jvisualvm分析  
     MAT分析  
     解决方案  
     案例3:GC overhead limit exceeded    
     案例模拟    
     示例代码1    
     JVM配置  
     报错信息  
     示例代码2    
     JVM配置  
     代码解析  
     分析及解决    
     第1步:定位问题代码块    
     jvisualvm分析  
     MAT分析  
     第2步:分析dump文件直方图  
     第3步:代码修改  
     案例4:线程溢出    
     报错信息    
     java.lang.OutOfMemoryError: unable to create new native Thread  
     问题原因    
     出现这种异常,基本上都是创建了大量的线程导致的  
     案例模拟    
     说明  
     示例代码  
     运行结果  
     分析及解决    
     解决方向1  
     解决方向2  
     性能优化案例    
     面试题  
     性能优化案例1:调整堆大小提高服务的吞吐量    
     修改Tomcat JVM配置  
     初始配置    
     查看日志  
     优化配置    
     查看日志  
     性能优化案例2:JVM优化之JIT优化  
     性能优化案例3:合理配置堆内存  
     特殊问题:新生代与老年代的比例  
     性能优化案例4:CPU占用很高排查方案  
     性能优化案例5:G1并发执行的线程数对性能的影响  
     性能优化案例6:调整垃圾回收器提高服务的吞吐量  
     性能优化案例7:日均百万级订单交易系统如何设置JVM参数    
     问题扩展  
     04_大厂面试题  
     
    收藏 
     
 
 
 
 
  0 条评论
 下一页
  
  
  
  
  
  
  
  
  
  
  
 