Java中,GC的对象是栈,堆空间和永久区
JVM运行时内存分区:
1.PC计数器:记录class文件执行到第几行
2.本地方法区:存放java中native方法
3.方法区(永久区:Perm区):常量,final常量放在次
4.栈:栈中存放的是栈贞,调用一个方法时,就会在栈中压入一个栈贞。栈贞中有局部变量表,存放局部变量。
基本类型存放在栈中,非基本类型存放在堆中,栈中只存放一个引用,这就是为什么java中基本类型是值传递,非基本类型是址传递
5.堆:所有new出来的对象都存放在堆中,它分为:eden,s0,s1,tenured
线程私有:PC计数器,栈
线程共有(共享):本地方法区,.方法区,堆
GC涉及哪几部分?答:堆,栈,方法区
STW现象:
Stop The World现象是每次GC时都会发生,其中新生代中发生的是min GC,一般STW时间较短,老年代发生的是FullGC,STW时间较长,主要就是优化FullGC
GC算法:
-标记清除
-标记压缩
-复制算法:将内存分为两个区域(from space和to space)。所有的对象分配内存都分配到from space。在清理非活动对象阶段,把所有标志为活动的对象,copy到to space,之后清楚from space空间。然后互换from sapce和to space的身份。既原先的from space变成to sapce,原先的to space变成from space。每次清理,重复上述过程。
标记清除与标记压缩对比:
清除时内存中会用碎片,不利于内存中连续内存空间的申请,如Java中数组的空间就是连续分配的,如下图是无法申请5个连续空间的
压缩则可以申请5个连续空间
GC Collector:
串行收集器
新生代、老年代使用串行回收
新生代复制算法
老年代标记-压缩
问题:可能会产生较长的停顿,只使用一个线程,在多核的情况下无法发挥作用
-XX:+UseSerialGC
Parallel收集器
新生代复制算法
老年代 标记-压缩
更加关注吞吐量
-XX:+UseParallelGC
新生代使用Parallel收集器+ 老年代串行
-XX:+UseParallelOldGC
新生代使用Parallel收集器+老年代也是使用Parallel收集器
问题:多线程收集器,但是多线程不一定快,要看CUP的核数,设置适当的线程数量
CMS收集器
Concurrent Mark Sweep 并发标记清除
标记-清除算法
新生代使用ParNew(:Serial的多线程版本,主要用于新生代收集。与CMS收集器配合成为现在最常用的server收集器)+老年代收集器使用CMS
-XX:+UseConcMarkSweepGC
问题:与标记-压缩相比并发阶段会降低吞吐量
CMS执行过程如下:
-初始标记
根可以直接关联到的对象
速度快
-并发标记(和用户线程一起)
主要标记过程,标记全部对象
-重新标记
由于并发标记时,用户线程依然运行,因此在正式清理前,再做修正
-并发清除(和用户线程一起)
基于标记结果,直接清理对象
-内存压缩
把内存中的碎片都压缩到一起
-XX:+ UseCMSCompactAtFullCollection Full GC后,进行一次整理
整理过程是独占的,会引起停顿时间变长
-XX:+CMSFullGCsBeforeCompaction
设置进行几次Full GC后,进行一次碎片整理
-XX:ParallelCMSThreads
设定CMS的线程数量