Java内存模型
-
虚拟机栈(线程私有)
局部变量表、操作数栈、动态链表、方法出口等信息 -
堆(线程共享)
实例对象 -
方法区(线程共享)
类信息、常量、即时编译器编译后的代码 -
程序计数器(线程私有)
字节码行号指示器,记录当前线程执行到哪一行 -
本地方法栈(线程私有)
和虚拟机栈类似,虚拟机栈为虚拟机执行java方法的服务;本地方法栈是为虚拟机执行native方法的服务
程序计数器
线程计数器中如果正在执行java方法,计数器记录的是当前指令的地址
如果是native方法,计数器记录为空
堆
堆内存=新生代+老年代
-
新生代
复制算法 -
老年代理
标记整理算法
方法区
也叫永久代,1.8以后将方法区移除了, 将方法区移动到直接内存
内存回收主要考虑的时候堆区和方法区的回收,其他部分会根据线程的产生和消亡
1.8删除方法区,引入直接内存,元空间概念,方法区中的静态变量转移到堆中,只有class元数据在元空间
堆中老年代和方法区中永久代是绑定的,无论哪一方满了,都会触发双方的GC回收
GC垃圾回收
判断对象是否存活
- 引用计数算法(缺点:循环引用,计数永不为0)
- 可达性算法(二叉树中向下搜索,不存在引用链则对象不可用)
回收算法
- 标记清除算法:标记完对象后,对对象进行回收,使用在老年代
缺点:
标记和清除效率不高
产生大量碎片空间,产生空间浪费 - 复制算法:将可用对象复制到新的连续空间,删除之前的空间
缺点:
浪费50%的内存,复制长生存周期的对象效率低下,所以使用在新生代 - 标记整理算法:前期使用标记清除算法,后续使用整理算法,使用在老生代
- 分代收集算法:对数据进行分代,每一代执行不同的回收算法
网友评论