什么是垃圾
jvm中的垃圾就是指 没有任何引用指向的一个对象或者是多个对象(多个对象循环引用)
如何定位垃圾
- 引用计数法:标记对象引用次数,标记为0,就可以回收,但无法解决循环引用多个对象的垃圾情况
- 根可达算法:只要对象没有跟对象引用,就可以进行垃圾回收
Jvm里什么是根?
- 栈中的引用对象
- 方法区的常量对象
- 方法区中的静态成员
- nativie原生方法
常见的垃圾回收算法有什么
-
标记清除:对可以回收的垃圾进行清除,但清除后内存会产生碎片,位置不能连续
-
拷贝算法:需要拷贝一份内存空间,把要要回收的那块空间里的未回收的copy到新空间进行连续存储,copy完毕,把要回收的那块空间整体回收。没有碎片,但是浪费空间
-
标记压缩:每次对垃圾进行标记回收的时候,把存活的对象放到回收的位置,进行一次挪动,这样虽然每次压缩都能获得连续的空间,没有碎片,但是标记压缩的效率有点低
|
JVM内存的分代模型
- 新生代+老年代,部分老的垃圾回收器使用。新的都不用了
- 新生代+老年代+ 【永久代(1.7)/ 原数据区(1.8)MetaSpace】
- 永久代与原数据什么区别?
- 永久代必须指定大小,设置死了,运行期间如果过多对象,会溢出
- 元数据区大小无上限(受限于物理内存)
- 方法区(Method Area)存放在永久代/原数据区
- 永久代字符串常量放到永久代 1.8 放在堆里
- 新生代有eden+2个suvivor区域(s0 s1)
- YGC回收后,大部分对象会被回收,活的进入s0
- 再次YGC,活着的对象进入eden +s0 进入s1
- 再次YGC,eden+s1 进入s0 (s0 s1 可能频繁交换copying)
- 再次YGC,顽固活着(年龄足够)的对象进入老年代
- s区装不下的情况下 s区的对象会进入老年代
- 老年代存放 顽固一直活着的对象,老年代如果满了会触发Full Gc
堆内存逻辑分区
|
常见的垃圾回收器
|
年轻代回收算法
- Serial 年轻代 串行回收
- Parallel Scavenge:并行回收,比serial效率高
- Parnew:配合CMS的并行回收
老年代回收算法 - Serial Old :老年代serial回收算法
- Parallel Old:老年代并行回收算法
- CMS(Concurrent MarkSweep):老年代并发的,垃圾回收与程序同时运行,垫底STW时间到200ms
- G1(STW时间约10ms)
- ZGC( STW 时间约1ms) :PKC++
- Shenandoah
- Eplison
JVM调优的目的:
- 减少FULLGC
其他
- JDK1.8默认的垃圾回收:PS+parallelOld
- MinorGC == YGC
- MajorGC == FGC
JVM参数分类
-开头:标准参数,所有的HotSpot都支持
-X开头:非标准参数,特点版本的HotSpot支持
-XX开头:测试参数,未来有可能会被移除
-XX+PrintCommandLineFlags 命令行中打印JVM参数列表
-XX:+PrintFlagsFinal 最终参数值
-XX:+PrintFlagsInitial 默认参数值