JVM 内存划分与垃圾回收机制
1.JVM内存布局:
一.方法区:所有线程共享的,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,运行时常量池(Runtime Constant Pool)是方法区的一部分。
二.虚拟机栈:线程私有的,每个方法在被调用时就会创建一个栈帧,每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程
三Java堆:是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,对象实例在这里分配内存。是垃圾收集器(GC)管理的主要区域
垃圾回收机制:
在回收垃圾之前,首要要明确两个问题
1.什么是垃圾,
这个就涉及到垃圾回收策略,垃圾回收算法分为以下几种
一:标记-清楚算法 (最基础的垃圾回收算法)
标记-清除算法分为两个阶段:标记阶段和清除阶段。
标记阶段的任务是标记出所有需要被回收的对象,清除阶段就是回收被标记的对象所占用的空间。
缺点:标记-清除算法容易实现,但问题是,容易产生内存碎片,碎片太多可能会导致后续过程中需要为大对象分配空间时无法找到足够的空间而提前触发新的一次垃圾收集动作。
二:复制算法:
将可用内存按容量划分为大小相等的两块,每次只使用其中一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用的内存空间一次清理掉,这样一来就不容易出现内存碎片的问题。
优点:复制(Copying)算法实现简单,运行高效且不容易产生内存碎片,
缺点:使能够使用的内存缩减到原来的一半。复制算法的效率跟存活对象数目多少有很大的关系,如果存活对象很多,那么Copying算法的效率将大大降低。
三:标记-整理算法
该算法标记阶段和标记-清除(Mark-Sweep)一样,但是在完成标记之后,它不是直接清理可回收对象,而是将存活对象都向一端移动,然后清理掉端边界以外的内存。
四:分代回收算法
jvm其实是将内存中的对象放在了不同的内存区域新生代和老年代,根据不同区域的特点,使用不同的垃圾啊回收策略
一:新生代的算法:采用了GC的复制算法,速度快,因为新生代一般是新对象,都是瞬态的用了可能很快被释放的对象。
二:老年代的算法 标记/整理算法,GC后会执行压缩,整理到一个连续的空间,这样就维护着下一次分配对象的指针,下一次对象分配就可以采用碰撞指针技术,将新对象分配在第一个空闲的区域。
2.有了垃圾之后如何回收
jvm垃圾回收器其实是分为:
1串行垃圾回收器
Serial/Serial Old
它是一个单线程收集器,并且在它进行垃圾收集时,必须暂停所有用户线程。
Serial收集器是针对新生代的收集器,采用的是复制算法,Serial Old收集器是针对老年代的收集器,采用的是标记-整理算法。
优点是实现简单高效,缺点是会给用户带来停顿。
2并行垃圾回收器(吞吐量)
并行收集器:多条垃圾收集线程并行工作,而用户线程仍处于等待状态
ParNew:
ParNew收集器是Serial收集器的多线程版本,使用多个线程进行垃圾收集
Parallel Scavenge:
该收集器是一个新生代的多线程收集器(并行收集器),它在回收期间不需要暂停其他用户线程,其采用的是Copying复制算法,
Parallel Old:
该收集器是Parallel Scavenge收集器的老年代版本(并行收集器),使用多线程和Mark-Compact(标记-整理)算法。
3并发垃圾回收器
并发收集器:垃圾收集线程与用户线程一段时间内同时工作(不是并行,而是交替执行)
CMS(Concurrent Mark Sweep):
CMS收集器是一种以获取最短回收停顿为目标的收集器,它是一种并发收集器,采用的是Mark-Sweep(标记-清除)算法。
G1:
G1收集器是一款面向服务端应用的收集器,它能充分利用多CPU、多核环境。G1收集器是一款并行与并发收集器,并且它能建立可预测的停顿时间模型。