堆:存放所有new出来的东西。GC堆是Java虚拟机所管理的内存中最大的一块内存区域,也是被各个线程共享的内存区域。堆被分为新生代和老年代。
方法区:存储虚拟机加载的类信息,常量,静态变量,各个内存共享的内存区域。默认大小为16mb,最大值为64mb
虚拟机栈:描述的是Java方法执行的内存模型。每一个方法被执行的时候,都会创建一个“栈帧”,用于存储局部变量表,操作栈,方法出口等。
本地方法栈:为Native方法服务。
程序计数器:分支、循环、跳转、异常处理、线程恢复。
1.标记-清除算法:该算法分为两个阶段:
1>标记阶段:找到所有可访问的对象,做个标记
2>清除阶段:遍历堆,找到未被标记的对象回收
优点:
1>可以解决循环引用的问题
2>必要时才回收
缺点:
1>回收时,应用需要挂起,也就是stop the world.
2>标记和清除的效率不高,尤其是扫描的对象比较多的时候
2.复制算法:
首先将内存分为大小相等的两部分(假设A、B两部分),每次呢只使用其中的一部分(这里我们假设为A区),等这部分用完了,这时候就将这里面还能活下来的对象复制到另一部分内存(这里设为B区)中,然后把A区中的剩下部分全部清理掉。
优点:
吞吐量大,只需要遍历一次From空间Sweep需要遍历两次,而且只复制存活的对象。高速分配,不需要通过空闲链表直接在连续的内存上进行分配。没有碎片。与缓存兼容,复制存活对象时采用深度优先算法使相关联的对象都在附近。缺点:
堆的使用效率低,必须分配一个To,其不能分配对象。不兼容保守式GC算法,需要移动对象。递归调用,复制对象的深度优先算法是通过递归调用实现的,递归将消耗栈等资源。3.标记-整理算法:算法不直接对可回收对象进行清理,而是让所有可用的对象都向一端移动。然后直接清理掉边界意外的内存。
4.分带收集算法:
根据对象的存活周期不同将内存划分为新生代和老年代,存活周期短的为新生代,存活周期长的为老年代。这样就可以根据每块内存的特点采用最适当的收集算法。
新生代的中每次垃圾收集中会发现有大批对象死区,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。 老年代中因为对象的存活率高,没有额外的控件对它进行分配担保,就必须使用“标记-清扫”或者“标记-整理”算法来进行回收。