一,jvm中包含五个内存模型
1: 程序计数器
作用是 控制代码的执行顺序,记住代码当前执行的位置用来控制程序的执行,控制程序当前执行哪个方法,哪个语句,
当处于多线程的时候,每个线程单独都需要一个自己的程序计数器,来确定自己当前线程代码该按什么顺序执行,所 以它一定得是私有的,否则多线程就会起冲突
2: 堆
用来记录存放对象,堆当中会存放java的对象实例,从java1.7之后也会存常量池。
3:虚拟机栈:
用来执行方法的,会存储内部声明的变量,以及对象的引用,线程私有,动态链接,方法出口,操作数栈。
4:本地栈:
用来执行一些非java方法的,比如C++的方法,用Native关键字修饰 它是线程私有的,java程序员一般不用去关注。
5:方法区
存储一些类加载时的信息,线程共有,在1.8之前方法区中包含永久代,会存储常量等信息 ,从1.6开始Java就开始着手移除永久代,在1.8的时候永久代完全移除,永久代变成了元空间 ,字面量和静态变量等数据移到了java heap中,其它数据移到了元空间,比如运行时常量池。
移除永久代,添加元空间的目的
1.类的大小不好控制,所以永久代的大小也不好控制。
2.永久代中的数据会增添GC在进行垃圾回收时候的压力。
二,GC自动垃圾回收机制
1,垃圾判断机制有两种
一.引用计数法
判断对象被使用了多少次,在程序中,每个对象都有一个计数器,对象每被引用一次,该计数器数字+1,只回收数字为0的对象
优点:回收速度快,简单
缺点:如果出现了1对1关系,互相引用,那么该数据永远不会被回收,且也可能永远不会被用到
二.可达性分析法:GC Root
现代虚拟机基本都是采用可达性分析算法来判断对象是否存活,可达性算法的原理是以一系列叫做 GC Root 的对象为起点出发,引出它们指向的下一个节点,再以下个节点为起点,引出此节点指向的下一个结点。这样通过 GC Root 串成的一条线就叫引用链),直到所有的结点都遍历完毕,如果相关对象不在任意一个以 GC Root 为起点的引用链中,则这些对象会被判断为垃圾对象,会被 GC 回收。
2,垃圾回收算法-四种
1,标记清除: Mark Sweep
先标记不需要清除的数据,然后清除掉剩下的所有数据 优点是回收速度快,但是空间利用率不高,会产生空间的浪费
2,标记整理: Mark Compact
先标记不需要清除的数据,然后清除掉剩下的数据,然后将没有被清除的数据整理到一端,特点是没有浪费空间,但是时间比标记清除要长一点
3,复制算法 :Copy
首先将内存分成两部分,A和B ,先使用A的内存, 垃圾回收时,判断出哪些数据不用回收,将它一次性复制到B处,然后将A的数据全部清空,特点是清空速度会快一点,但是直接浪费了一半的空间
4,分代算法
1. 新生代:复制算法
2. 老年代:标记整理算法
注:如有说错或缺少可以把你们宝贵的意见写在评论区,看到后会第一时间修改,谢谢!