内存模型:
(1)程序计数器
(2)虚拟机栈
(3)本地方法栈
(4)堆
(5)方法区
注意:堆和方法区是线程共享的,其余区域是线程隔离的。
栈里面存放的是基本的数据类型和引用,而堆里面则是存放各种对象实例的。
垃圾回收机制的算法:
(1)引用计数法
堆中的每个对象实例都有一个引用计数。当一个对象被创建时,且将该对象分配给一个变量,该变量计数设置为1。当任何其他变量被赋值为这个对象的引用时,计数加1,但当一个对象实例的某个引用超过了生命周期或者被设置为一个新值时,对象实例的引用计数器减一。任何引用计数器为0的对象实例可以被当作垃圾收集。
(2)标记-清除法(引用链法)
通过一种GCROOT的对象来判断,如果有一条能够达到GCROOT就对该对象标记为存活,其他对象则标记为不存活,存活对象比较多的情况下很高效,但是容易造成内存碎片
(3)标记-整理法
标记-整理算法采用标记-清除算法一样的方式给对象进行标记,但在清除时不同,在回收不存活的对象占用的空间时,会将所有的存活对象向左移动,并更新对应的指针。虽然增加了对象的移动,成本增加,但是解决了内存碎片的问题
(4)复制算法
将内存划分为等大小的两块,每次只使用其中一块,当一块内存满后将尚存活的对象复制到另一块上去,把已使用的内存清除。这种算法不容易产生内存碎片,但是内存被压缩到只有一半了,且存活对象增多的话,效率会降低
(5)generation collection算法(分代收集算法)
由于不同的对象的生命周期是不一样的。因此,不同生命周期的对象可以采取不同的回收算法,可以提高回收效率。
年轻代:(采用copying算法)
1.所有新生成的对象首先放在年轻代。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。
2.新生代内存按照8:1:1的比例分为一个eden区和两个survivor(from,to)区。一个Eden区,两个Survivor区。大部分对象在Eden区中生成。如果eden区满了或者放不下了,这时候其中存活的对象复制到from区(如果存活下来的对象from区都放不下,则这些存活的对象全部进入老年代),之后eden区全部回收掉。如果from区的也满了,再次执行Minor GC则会将eden区存活的和from存活的全部复制到to,(此时from和eden区都是空的,from和to互换角色,from变为to,to变为from)。之后每执行一次Minor GC都会将存活对象复制到from(原来的to),互换多次之后,对象的年龄(执行一次Minor GC则增加1岁)超过一定年龄则会复制到老年代(老年代执行Full GC)
老年代:
1.在年轻代中经理了N次垃圾回收后仍然存活的对象,就会被放到老年代中。
2.内存比新生代大很多,当老年代内存满时触发Major GC即Full GC
持久代: