JVM内存区域:
私有区:
1.程序计数器:线程所执行的字节码的行号指示器,用于记录正在执行的虚拟机字节指令地址;
2.栈 :存放基本数据类型、对象的引用;
3.本地方法区:和虚拟栈相似,只不过它服务于Native方法;
共有区:
1.堆:java内存最大的一块,所有对象实例、数组都存放在java堆,GC回收的地方;
2.方法区:存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码数据等。(即永久带),回收目标主要是常量池的回收和类型的卸载;
GC回收机制:
JAVA中对象是通过new()或者反射创建的对象实例都存在堆中,所以对象的回收都是由JAVA虚拟机的垃圾回收完成的,GC为了能够正确的释放对象,会监控每个对象的运行状态;
如何确定垃圾:
引用计数算法:给对象添加一个引用计数器,有引用+1,引用失效-1,当值为0,就表示可以被GC回收了;
可达性算法:通过对GC roots对象作为起点,从这些起点开始向下搜索,搜索走过的路径称为引用链,当一个对象没有任何引用链相连时代表可以被GC了;
GC有哪些回收算法:
标记-清除法:标记出没有用的对象,然后一个一个回收掉 ;
缺点:标记和清除两个过程效率不高,产生过多的内存碎片;
复制算法: 按照容量划分二个大小相等的内存区域,当一块用完的时候,将存活的复制到另一块上;再把已使用的清除掉;
缺点:将内存缩小为原来的一半;
标记-整理算法:标记出没有用的对象,将有用的全部移入另一半,然后直接清除没有用的;
优点:解决了标记-清除算法内存碎片问题;
分代回收:根据对象存活周期的不同,划分为新生代,老年化;新生代基于复制算法,老年代基于标记-整理算法;
JAVA堆是如何GC的?
首先按1:2划分,分为新生代,老年代;
新生代又分三个区:
eden 8:from 1:to 1
Eden区:JAVA新对象的出生地,如果新对象的内存占用很大会直接进入老年代。当Eden区内存不够时,会触发GC;
ServivorFrom:上次GC的辛存哲,作为本次GC的被扫描者;
ServivorTo:本次的幸存者;
MinorGC的过程,复制-》清空-》互换;
具体过程:
1.首先将Eden区 和 ServivorFrom存活的对象复制到 ServicorTo区域,并且年龄+1;
2.清空eden,和ServivorFrom区域;
3.将ServicorTo与ServivorFrom互换,原ServivorTo,作为下一次被扫描的对象;
当年龄超过15时,进入老年代;