GC(Garbage Collection) 简称垃圾收集 垃圾回收html
JVM运行时数据区:java
1.方法区存储类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等算法
2.堆(heap)存储对象的信息,分为新生代(Eden,Survivor1,Survivor2)和老年代,永久代apache
3.程序计数器,存储的数据所占空间的大小不会随程序的执行而发生改变,所以,对于程序计数器是不会发生内存溢出现象(OutOfMemory)的浏览器
4.Java栈(stack)是Java方法执行的内存模型tomcat
5.本地方法栈则是为执行本地方法(Native Method)服务的app
讲到垃圾回收,那么何时对象须要回收,如何去判断对象是存活仍是死亡,咱们采用引用计数法来判断对象是否存活,当一个对象被引用时,计数器值加1,当引用失效时减1.less
强引用与弱引用的区别:eclipse
强引用:相似Object obj = new Object();只要强引用还存在,垃圾回收器不会收集被引用的对象jvm
软引用:用来描述还有用但非必需的对象
经过可达性分析算法来判断对象是否须要被回收
垃圾回收策略有 标记清除法(会产生过多的内存碎片),复制法(内存使用率不高),标记整理法
垃圾收集器分类
Serial收集器:发展历史最悠久的收集器
ParNew收集器
Minor GC & Major GC & Full GC
从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC
CMS(Concurrent Mark Sweep)收集器:是一种以获取最短停顿时间为目标的垃圾收集器
jps(Java Virtual Machine Process Status Tool);//虚拟机进程情况工具 jstat;//虚拟机统计信息监视工具 jstat -gcutil 19473;//统计gc信息 jstat -gc 4588 250 20;//每250毫秒查询进程4588垃圾收集状况 一共查询20次 jstat -gcold 4588;//查看老年代gc存储量 jstat -gcnew 4588;//查看年轻代gc存储量 -gc:监视堆内存状况,包括eden区,s1,s2,老年代和永久代的内存容量 -gcnew:监视新生代GC状况 -gcold:监视老年代GC状况 jinfo;//Java配置信息工具 jmap;//java内存映像工具 使用jmap生成dump文件 jmap -dump:format=b,file=eclipse.bin 14949;//14949进程号 jhat;//虚拟机堆转储快照分析工具 jstack;//java堆栈跟踪工具
jps是用于查询jvm进程信息的
主要参数有:
-q 不输出类名、Jar名和传入main方法的参数 -m 输出传入main方法的参数 -l 输出main类或Jar的全限名 -v 输出传入JVM的参数
好比输入
jps -m -l
15089 org.apache.catalina.startup.Bootstrap start 27362 org.apache.catalina.startup.Bootstrap start 9043 org.apache.catalina.startup.Bootstrap start 9765 sun.tools.jps.Jps -m -l 8328 org.apache.catalina.startup.Bootstrap start 27179 org.apache.zookeeper.server.quorum.QuorumPeerMain /usr/local/zookeeper-3.4.6/bin/../conf/zoo.cfg 31454 org.apache.catalina.startup.Bootstrap start
jstack主要用来查看某个Java进程内的线程堆栈信息
jstack -F 2881
主要参数有:
-F to force a thread dump. Use when jstack <pid> does not respond (process is hung) -m 不只会输出Java堆栈信息,还会输出C/C++堆栈信息(好比Native方法) -l 会打印出额外的锁信息,在发生死锁时能够用jstack -l pid来观察锁持有状况 -h or -help to print this help message
jmap用来查看堆内存使用情况,通常结合jhat使用
jmap -heap 7481 jmap -histo:live 1432 | more;//查看堆内存中的对象数目、大小统计直方图,若是带上live则只统计活对象 jmap -permstat 7481;//若是操做系统是64位
打印进程的类加载器和类加载器加载的持久代对象信息,输出:类加载器名称、对象是否存活(不可靠)、对象地址、父类加载器、已加载的类大小等信息
使用jmap -heap pid查看进程堆内存使用状况,包括使用的GC算法、堆配置参数和各代中堆内存使用状况
[root@localhost ~]# jmap -heap 7481 Attaching to process ID 7481, please wait... Debugger attached successfully. Server compiler detected. JVM version is 24.76-b04 using thread-local object allocation. Parallel GC with 4 thread(s) Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 MaxHeapSize = 1981808640 (1890.0MB) NewSize = 1310720 (1.25MB) MaxNewSize = 17592186044415 MB OldSize = 5439488 (5.1875MB) NewRatio = 2 SurvivorRatio = 8 PermSize = 21757952 (20.75MB) MaxPermSize = 85983232 (82.0MB) G1HeapRegionSize = 0 (0.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 31981568 (30.5MB) used = 11806536 (11.259590148925781MB) free = 20175032 (19.24040985107422MB) 36.916689012871416% used From Space: capacity = 4718592 (4.5MB) used = 0 (0.0MB) free = 4718592 (4.5MB) 0.0% used To Space: capacity = 4718592 (4.5MB) used = 0 (0.0MB) free = 4718592 (4.5MB) 0.0% used PS Old Generation capacity = 82313216 (78.5MB) used = 0 (0.0MB) free = 82313216 (78.5MB) 0.0% used PS Perm Generation capacity = 22020096 (21.0MB) used = 5066136 (4.831443786621094MB) free = 16953960 (16.168556213378906MB) 23.00687517438616% used 2942 interned Strings occupying 249928 bytes.
一个很经常使用的状况是:用jmap把进程内存使用状况dump到文件中,再用jhat分析查看。jmap进行dump命令格式以下:
jmap -dump:format=b,file=dumpFileName pid jmap -dump:format=b,file=/tmp/dump.dat 21711 jmap -dump:live,format=b,file=xxx 2657
用jhat分析dump文件:
jhat -port 9998 /tmp/dump.dat
浏览器端输入http://localhost:9998 能够看到下面的页面:
jstat(JVM统计监测工具)
jstat -gc 21711 250 4;//输出的是GC信息,采样时间间隔为250ms,采样数为4
输入内容为:
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 1024.0 1024.0 0.0 544.1 28672.0 23313.6 142336.0 98745.4 57984.0 55759.5 7040.0 6445.8 1213 8.115 3 0.322 8.437 1024.0 1024.0 0.0 544.1 28672.0 23313.6 142336.0 98745.4 57984.0 55759.5 7040.0 6445.8 1213 8.115 3 0.322 8.437 1024.0 1024.0 0.0 544.1 28672.0 23315.6 142336.0 98745.4 57984.0 55759.5 7040.0 6445.8 1213 8.115 3 0.322 8.437 1024.0 1024.0 0.0 544.1 28672.0 23317.7 142336.0 98745.4 57984.0 55759.5 7040.0 6445.8 1213 8.115 3 0.322 8.437
要明白上面各列的意义,先看JVM堆内存布局:
能够看出:
堆内存 = 年轻代 + 年老代 + 永久代 年轻代 = Eden区 + 两个Survivor区(From和To)
如今来解释各列含义:
S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used) EC、EU:Eden区容量和使用量 OC、OU:年老代容量和使用量 PC、PU:永久代容量和使用量 YGC、YGT:年轻代GC次数和GC耗时 FGC、FGCT:Full GC次数和Full GC耗时 GCT:GC总耗时
JVM参数含义
-Xms 是指设定程序启动时占用内存大小,通常来说,大点,程序会启动的 快一点,可是也可能会致使机器暂时间变慢。 -Xmx 是指设定程序运行期间最大可占用的内存大小。若是程序运行须要占 用更多的内存,超出了这个设置值,就会抛出OutOfMemory 异常。 -Xss 是指设定每一个线程的堆栈大小。这个就要依据你的程序,看一个线程 大约须要占用多少内存,可能会有多少线程同时运行等。 -Xmn 新生代大小
tomcat内存设置
CATALINA_OPTS="$CATALINA_OPTS -server -Djava.awt.headless=true -Xms5000m -Xmx5000m -Xss256k -XX:PermSize=128m -XX:MaxPermSize=384m -XX:NewSize=4000m -XX:MaxNewSize=4000m -XX:SurvivorRatio=22 -XX:+UseParNewGC -XX:ParallelGCThreads=4 -XX:MaxTenuringThreshold=9 -XX:+UseConcMarkSweepGC -XX:+DisableExplicitGC -XX:+UseCMSInitiatingOccupancyOnly -XX:+ScavengeBeforeFullGC -XX:+UseCMSCompactAtFullCollection -XX:+CMSParallelRemarkEnabled -XX:CMSFullGCsBeforeCompaction=9 -XX:CMSInitiatingOccupancyFraction=60 -XX:+CMSClassUnloadingEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:-ReduceInitialCardMarks -XX:+CMSPermGenSweepingEnabled -XX:CMSInitiatingPermOccupancyFraction=70 -XX:+ExplicitGCInvokesConcurrent -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationConcurrentTime -XX:+PrintHeapAtGC -Xloggc:/data/applogs/heap_trace.txt -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/applogs/HeapDumpOnOutOfMemoryError" CATALINA_OPTS="$CATALINA_OPTS -Duser.timezone=Asia/Shanghai -Dclient.encoding.override=UTF-8 -Dfile.encoding=UTF-8" CATALINA_OPTS="$CATALINA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"
tomcat启动参数参考
-Xms20288m -Xmx20288m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewSize=10144m -XX:MaxNewSize=10144m -XX:SurvivorRatio=10
标准配置参考配置catalina.sh(http://www.cnblogs.com/oskyhg/p/6549877.html)
CATALINA_OPTS="$CATALINA_OPTS -server -Djava.awt.headless=true -Xms5000m -Xmx5000m -Xss256k -XX:PermSize=128m -XX:MaxPermSize=384m -XX:NewSize=4000m -XX:MaxNewSize=4000m -XX:SurvivorRatio=22 -XX:+UseParNewGC -XX:ParallelGCThreads=4 -XX:MaxTenuringThreshold=9 -XX:+UseConcMarkSweepGC -XX:+DisableExplicitGC -XX:+UseCMSInitiatingOccupancyOnly -XX:+ScavengeBeforeFullGC -XX:+UseCMSCompactAtFullCollection -XX:+CMSParallelRemarkEnabled -XX:CMSFullGCsBeforeCompaction=9 -XX:CMSInitiatingOccupancyFraction=60 -XX:+CMSClassUnloadingEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:-ReduceInitialCardMarks -XX:+CMSPermGenSweepingEnabled -XX:CMSInitiatingPermOccupancyFraction=70 -XX:+ExplicitGCInvokesConcurrent -Djava.nio.channels.spi.SelectorProvider=sun.nio.ch.EPollSelectorProvider -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationConcurrentTime -XX:+PrintHeapAtGC -Xloggc:/data/applogs/heap_trace.txt -XX:-HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/applogs/HeapDumpOnOutOfMemoryError" CATALINA_OPTS="$CATALINA_OPTS -Duser.timezone=Asia/Shanghai -Dclient.encoding.override=UTF-8 -Dfile.encoding=UTF-8"
重要概念
-Xmx10240m:表明最大堆 -Xms10240m:表明最小堆 -Xmn5120m:表明新生代 -XXSurvivorRatio=3:表明Eden:Survivor= 3 根据Generation-Collection算法(目前大部分JVM采用的算法),通常根据对象的生存周期将堆内存分为若干不一样的区域,通常状况将新生代分为Eden,两块Survivor; 计算Survivor大小分别比为3:1:1,Eden:Survivor =3,总大小为5120,3x+x+x=5120 x=1024 新生代大部分要回收,采用Copying算法,快! 老年代 大部分不须要回收,采用Mark-Compact算法- 标记清除算法
4.JVM性能调试工具
经常使用的JVM调试工具备visualvm(http://visualvm.java.net/),heap analyzer