JVM 原理与实战
JVM
JVM内存模型
五部分
概述
内存分配
JVM整体结构
类加载
类加载概念
类加载流程
双亲委派模型
自定义类加载器
双亲委派的破坏-线程上下文类加载器
Tomcat类加载器器结构
垃圾回收
finalize
引用级别
强引用
软引用
弱引用
虚引用
垃圾回收算法
什么是垃圾回收
垃圾回收算法
引用计数法:java不用
标记清除算法
复制算法
标记压缩算法(标记整理)
分代算法
分区算法
串行回收器
Serial
Serial Old
并行回收器
Parallel New
Parallel Scavenge ParallelGC
Parallel Old ParallelOldGC
CMS :并发标记清除
G1回收器
混合收集
JVM参数
常用参数
Java [-options] [package+className] [arg1,arg2,…,argN] options: -Xms128m 设置初始化堆内存为128M -Xmx512m 设置最大堆内存为512M -Xmn160m 设置新生代大小为-Xmn160M(堆空间1/4~1/3) -Xss128m 设置最大栈内存为128M -XX:SurvivorRatio 设置新生代eden区与from/to空间的比例关系 -XX:PermSize=64M 设置初始永久区64M -XX:MaxPermSize=128M 设置最大永久区128M -XX:MaxMetaspaceSize 设置元数据区大小(JDK1.8 取代永久区) -XX:+DoEscapeAnalysis 启用逃逸分析(Server模式) -XX:+EliminateAllocations 开启标量替换(默认开启) -XX:+TraceClassLoading 跟踪类的加载 -XX:+TraceClassUnloading 跟踪类的卸载 -Xloggc:gc.log 将gc日志信息打印到gc.log文件中 -XX:+PrintGC 打印GC日志 -XX:+PrintGCDetails ** 打印GC详细日志 -XX:+PrintGCTimeStamps ** 输出GC发生的时间 -XX:+PrintGCApplicationStoppedTime GC产生停顿的时间 -XX:+PrintGCApplicationConcurrentTime 应用执行的时间 -XX:+PrintHeapAtGC 在GC发生前后,打印堆栈日志 -XX:+PrintReferenceGC 打印对象引用信息 -XX:+PrintVMOptions 打印虚拟机参数 -XX:+PrintCommandLineFlags 打印虚拟机显式和隐式参数 -XX:+PrintFlagsFinal 打印所有系统参数 -XX:+PrintTLAB ** 打印TLAB相关分配信息 -XX:+UseTLAB 打开TLAB -XX:TLABSize 设置TLAB大小 -XX:+ResizeTLAB 自动调整TLAB大小 -XX:+DisableExplicitGC 禁用显示GC (System.gc()) -XX:+ExplicitGCInvokesConcurrent 使用并发方式处理显式GC
JVM监控优化
Visual VM
命令
top
能够实时显示系统中各个进程的资源占用情况。
分为两部分:系统统计信息&进程信息。
系统统计信息:
Line1:任务队列信息,从左到右依次表示:系统当前时间、系统运行时间、当前登录用户数。
Load average表示系统的平均负载,即任务队列的平均长度——1分钟、5分钟、15分钟到现在的平均值。
Line2:进程统计信息,分别是:正在运行进程数、睡眠进程数、停止的进程数、僵尸进程数。
Line3:CPU统计信息。us表示用户空间CPU占用率、sy表示内核空间CPU占用率、ni表示用户进程空间改变过优先级的进程CPU占用率。id表示空闲CPU占用率、wa表示待输入输出的CPU时间百分比、hi表示硬件中断请求、si表示软件中断请求。
Line4:内存统计信息。从左到右依次表示:物理内存总量、已使用的物理内存、空闲物理内存、内核缓冲使用量。
Line5:从左到右表示:交换区总量、已使用交换区大小、空闲交换区大小、缓冲交换区大小。 进程信息: PID:进程id USER:进程所有者 PR:优先级 NI:nice值,负值高优先级,正值低优先级 VIRT:进程使用虚拟内存总量 VIRT=SWAP+RES RES:进程使用并未被换出的内存。CODE+DATA SHR:共享内存大小 S:进程状态。 D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程 %CPU:上次更新到现在的CPU时间占用百分比 %MEM:进程使用的物理内存百分比 TIME+:进程使用的CPU时间总计,单位 1/100秒 COMMAND:命令行
vmstat性能监测工具,显示单位均为kb。它可以统计CPU、内存使用情况、swap使用情况等信息,也可以指定采样周期和采用次数。例如:每秒采样一次,共计3次。 procs列:r表示等待运行的进程数。b表示处于非中断睡眠状态的进程数。 memory列:swpd表示虚拟内存使用情况。free表示空闲内存量。buff表示被用来作为缓存的内存。 swap列:si表示从磁盘交换到内存的交换页数量。so表示从内存交换到磁盘的交换页数量。 io列:bi表示发送到块设备的块数,单位:块/秒。bo表示从块设备接收到的块数。 system列:in表示每秒的中断数,包括时钟中断。cs表示每秒的上下文切换次数。 cpu列:us表示用户cpu使用时间。sy表示内核cpu系统使用时间。id表示空闲时间。 wa表示等待io时间。
iostat可以提供详尽的I/O信息。 如果只看磁盘信息,可以使用-d参数。即:Iostat –d 1 3 (每1秒采集一次持续3次) tps列表示该设备每秒的传输次数。 Blk_read/s列表示每秒读取块数。 Blk_wrtn/s列表示每秒写入块数。 Blk_read列表示读取块数总量。 Blk_wrtn列表示写入块数总量。
jps 用于列出Java的进程。 执行语法: jps [-options]
jps 列出java进程id和类名 91275 FireIOTest jps –q 仅列出java进程id 91275 jps –m 输出java进程的入参 91730 FireIOTest a b jps –l 输出主函数的完整路径 91730 day1.FireIOTest jps –v 显示传递给JVM的参数 91730 FireIOTest -Xmx512m -XX:+PrintGC -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=51673:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8
jstat用于查看堆中的运行信息。 执行语法:jstat –help jstat -options jstat <-option> [-t] [-h<lines>] <vmid> [<interval> [<count>]] jstat -class -t 73608 1000 5 查看进程73608的ClassLoader相关信息,每1000毫秒打印1次,一共打印5次,并输出程序启动到此刻的Timestamp数。 jstat -compiler -t 73608 查看指定进程的编译信息。 jstat -gc 73608 查看指定进程的堆信息。 Jstat -gccapacity 73608 查看指定进程中每个代的容量与使用情况 jstat -gccause 73608 显示最近一次gc信息 jstat -gcmetacapacity 73608 查看指定进程的元空间使用信息 jstat -gcnew 73608 查看指定进程的新生代使用信息 jstat -gcnewcapacity 73608 查看指定进程的新生代各区大小信息 jstat -gcold 73608 查看指定进程的老年代使用信息 jstat -gcoldcapacity 73608 查看指定进程的老年代各区大小信息 jstat -gcutil 73608 查看指定进程的GC回收信息 jstat -printcompilation 73608 查看指定进程的JIT编译方法统计信息
jinfo用于查看运行中java进程的虚拟机参数。 执行语法: jinfo [option] <pid> jinfo -flag MaxTenuringThreshold 73608 查看进程73608的虚拟机参数MaxTenuringThreshold的值 jinfo -flag +PrintGCDetails 73608 动态添加进程73608的虚拟机参数+PrintGCDetails,开启GC日志打印。 jinfo -flag -PrintGCDetails 73608 动态添加进程73608的虚拟机参数+PrintGCDetails,关闭GC日志打印。
jmap命令用于生成指定java进程的dump文件;可以查看堆内对象实例的统计信息,查看ClassLoader信息和finalizer队列信息。 执行语法: jmap [option] <pid> jmap -histo 73608 > /Users/muse/a.txt 输出进程73608的实例个数与合计到文件a.txt中 jmap -dump:format=b,file=/Users/muse/b.hprof 73608 输出进程73608的堆快照,可使用jhat、visual VM等进行分析
jhat命令用于分析jmap生成的堆快照。 执行语法: jhat [-stack <bool>] [-refs <bool>] [-port <port>] [-baseline <file>] [-debug <int>] [-version] [-h|-help] <file>
jstack命令用于导出指定java进程的堆栈信息
CPU 占用过高问题排查
查看系统状况
通过top 找到过载的pid
定位现成问题
使用ps -mp pid -o THREAD,tid,time 查看该进程的线程情况。
查看问题线程堆
将线程id换位16进制
就stack查看堆栈信息
jstack pid |grep tid //十六进制
jstat查看进程内存状况
jstat -gcutil 6764 2000 10 查看垃圾回收统计
jstack和jmap分析进程堆栈和内存状况
使用jmap命令导出heapdump文件,然后拿到本地使用mat、jprofile等工具
jmap -dump:format=b,file=dump.bin 1
jstack vmid
jstack -l 2 >> jstack.out
从dump文件定位程序中的共从现场
评论