1.什么是垃圾
c语言申请内存 malloc 释放内存 free
c++: new delete
java: new
自动内存回收 优点:编程上简单,手动释放内存,容易出两种类型的问题:
1.忘记回收
2多次回收
jvm的调优呢,主要就是集中在垃圾回收机制的选择和参数设置
定义:没有任何引用执行那个的一个对象或者多个对象(循环引用)
2.如何定位垃圾
- 引用计数 但是无法循环引用的垃圾,就是一堆垃圾
- 根可达算法 Java虚拟机中就是采用这种方式
理解 GC roots包含的变量。通过根找不到的对象就是垃圾
3.常见的垃圾回收算法
-
Mark-Sweep(标记清除) 位置不连续,产生碎片
就是找到垃圾,把他标记成非垃圾区域
-
Copying(拷贝)
把内存分成两半,只用其中一般,当垃圾回收的时候,我们把存活的对象拷贝到另一半如上图所示。再把上边那块全部清掉,下边的清垃圾了,就考到上边,然后下边全清空,来回重复。
快,但是浪费空间
-
Mark-Compact(标记压缩)
再回收的时候,将后边的存活的对象,依次填充到前边未使用或者可回收的磁盘块中,做一个整理,如上图。
可是这个效率比copy低。没有碎片。任何一块挪动都要进行线程同步
4.jvm内存分代模型(用于分代垃圾回收算法)
1.在部分垃圾回收器,会把jvm分成各种代,也就是不同的区域。(部分)
比较新的垃圾回收器,他就不使用代,比如说G1
->2. 新生代+老年代+永久代(1.7)/元数据区(1.8)Metaspace
- 永久代 和 元数据 装class对象的
- 永久代必须指定大小限制(将来会出现限制),元数据区可以设,也可以不设置,无上限(受限于物理内存)
- 字符串常量 1.7 存在永久代 1.8 在堆里
- 元数据区,jvm都不去管他了,它受限于操作系统。永久代1.7 好像是在堆里
MethodArea 是一个逻辑概念,在永久代 或 元数据区
3. 运行时
上边数字就是每个区的比。了解每个区是怎么使得呢,我们就需要知道一个对象产生得过程。
当我们new一个对象,默认去eden去找空间,如果盛不开,直接去老年代。两个survivor 便于垃圾回收(YGC回收之后,大多数的对象都会被清楚),在新生代这生曾的对象,很容易回收。比如for循环中的对象。用copy算法,将eden区的活着的对象考到第一个survivor区,然后eden区清空。再次YGC之后,第一个survivor区和eden区的活着的对象考到第二个survivor区。再次YGC
把第二个sur。。区和eden 整到第一个sur区,清空。然后反复。如果survivor区的有那麽几个一直不被回收,直接进入老年代,成不来了也进入老年代。老年代就是兜底的
老年代满了就会触发Full GC(FGC),老年代就是就是装顽固分子的。
我们GC调优就是 减少FGC
FULL GC 就是新生代和老年代一起 进行回收的。
两个概念
MinorGC = YGC 年轻代垃圾回收
MajorGC = FGC
5 常见的垃圾回收器
10种垃圾回收器
图的说明
在中间的是不在用新生代和老年代了。上边就是用在新生代,下半部分就是用在老年代的。
待解G1。。只了解了分带模型
Serial()是新生代的垃圾回收器,垃圾回收时 停止所有线程,开始垃圾回收 单线程垃圾回收。卡顿是你程序卡顿了,可不是你的cpu,cpu永远有活干
ps 并行回收
parnew适合cms配合使用的,为了配合cms 在ps设计了parnew
cms 简单来说是在回收时不用 停止应用程序 不用stop the word