JVM
一,JVM内存结构
1,虚拟机栈:存储对象引用和基本数据类型,线程栈
2,堆:存放数组,new 的对象
3,方法区:存放类信息,方法名,包括常量池,存放一些string ,final,static 常量,可通过java -xx:PermSize -xx:maxpersize设置,对应隔代垃圾回收的永久代
4,本地方法区:存放native的一些类库,native方法
5,程序计数器:当前线程所执行的字节码的行号指示器
二,JVM垃圾回收机制
1,是隔代回收的,分为年轻带,年老带,永久区,年轻带分为edson区,和两个suviver区,edson+1个suer区和另外一个suvier区是8:1比例
2,垃圾回收流程
对象创建,可能放在edson区年轻带,也可能直接存放在年老带,可配置,一般如果是字符串或者数组过大的话直接放在年老带
回收过程分为 Minor回收和full回收,Minor回收即对年轻带进行回收,回收后,如果对象存活会把对象从edson区移动suiver区,采用的算法是复制算法,edson和其中的一段survier数据经过垃圾回收会被清空,存放在另外一段suiver区,如果另外一段suiver区不足以放下,需要年老带分配担保机制,进入年老带,full gc会对年老带和永久代进行垃圾的回收,采用的是标志整理算法
对象晋升 年龄阈值 VM为每个对象定义了一个对象年龄(Age)计数器, 对象在Eden出生如果经第一次Minor GC后仍然存活, 且能被Survivor容纳的话, 将被移动到Survivor空间中, 并将年龄设为1. 以后对象在Survivor区中每熬过一次Minor GC年龄就+1. 当增加到一定程度(-XX:MaxTenuringThreshold, 默认15), 将会晋升到老年代. 提前晋升: 动态年龄判定 然而VM并不总是要求对象的年龄必须达到MaxTenuringThreshold才能晋升老年代: 如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半, 年龄大于或等于该年龄的对象就可以直接进入老年代, 而无须等到晋升年龄.
-XX:MaxTenuringThreshold 晋升到老年代的对象年龄,每次Minor GC之后,年龄就加1,当超过这个参数的值时进入老年代
-XX:+UseCMSCompactAtFullCollection 由于CMS收集器会产生碎片,此参数设置在垃圾收集器后是否需要一次内存碎片整理过程,仅在CMS收集器时有效 -XX:+CMSFullGCBeforeCompaction 设置CMS收集器在进行若干次垃圾收集后再进行一次内存碎片整理过程,通常与UseCMSCompactAtFullCollection参数一起使用
三,垃圾回收标志
可达性分析算法 在主流商用语言(如Java、C#)的主流实现中, 都是通过可达性分析算法来判定对象是否存活的: 通过一系列的称为 GC Roots 的对象作为起点, 然后向下搜索; 搜索所走过的路径称为引用链/Reference Chain, 当一个对象到 GC Roots 没有任何引用链相连时, 即该对象不可达, 也就说明此对象是不可用的, 如下图: Object5、6、7 虽然互有关联, 但它们到GC Roots是不可达的, 因此也会被判定为可回收的对象:
在Java, 可作为GC Roots的对象包括
: 方法区: 类静态属性引用的对象; 方法区: 常量引用的对象; 虚拟机栈(本地变量表)中引用的对象. 本地方法栈JNI(Native方法)中引用的对象。
注: 即使在可达性分析算法中不可达的对象, VM也并不是马上对其回收, 因为要真正宣告一个对象死亡, 至少要经历两次标记过程: 第一次是在可达性分析后发现没有与GC Roots相连接的引用链, 第二次是GC对在F-Queue执行队列中的对象进行的小规模标记(对象需要覆盖finalize()方法且没被调用过).
四,JVM分析工具
jcmd:可强制回收
jstat
jconsole
jvisualvm JDK中最强大运行监视和故障处理工具 可以监控内存泄露、跟踪垃圾回收、执行时内存分析、CPU分析、线程分析…
jcmd GC.run 强制回收
jcmd 31275 Thread.print -l # 打印线程栈
jcmd 31275 VM.command_line # 打印启动命令及参数
jcmd 31275 GC.heap_dump /data/31275.dump # dump heap
jcmd 31275 GC.class_histogram #查看类的统计信息
jcmd 31275 VM.system_properties #查看系统属性内容
jcmd 31275 VM.uptime #查看虚拟机启动时间
jcmd 31275 PerfCounter.print #查看性能统计
五,什么时候触发
Minor GC触发条件:当Eden区满时,触发Minor GC。
Full GC触发条件: (1)调用System.gc时,系统建议执行Full GC,但是不必然执行
(2)老年代空间不足
(3)方法去空间不足
(4)通过Minor GC后进入老年代的平均大小大于老年代的可用内存
(5)由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小
生活案例比拟
躺在卧室里面看电视,床旁边有床头柜和一个小的垃圾桶,客厅有个大点的垃圾桶,当你扔比较大的垃圾时候会跑到客厅扔,比如说半个西瓜皮,不然的话房间的味不好,或者说垃圾桶一下被塞满了,你躺在看电视嗑瓜子,嗑瓜子时候先放在床头柜,床头柜满了就拉来卧室的垃圾桶,网垃圾桶里扔,卧室垃圾桶的垃圾差不多了就扔在客厅的垃圾桶中,最后出门的时候全部清理掉了!