JVM内存模型回收算法

JVM结构原理,GC工作机制

程序计数器(Program Counter (PC) Register):官方解释是指向当前线程正在执行的字节码指令的地址、行号。明明说了当前线程正在执行的字节码,为什么还要存储它的地址行号呢?原因是CPU工作的原理是有任务调度的,有可能该字节码没有执行完毕就被挂起啦,这样解释可能就容易理解了。

 虚拟机栈(Java Virtual Machine Stacks):栈是一种数据结构,数据结构是存储数据的,因此虚拟机栈就是当前线程运行方法是所需的数据、指令以及返回地址。虚拟机栈是first in last out,里面的每执行一个方法就是一个栈帧,递归的方法(进过实例测试递归多少次就会有多少栈帧)。     

本地方法栈 (Native Method Stacks):本地方法栈与虚拟机栈发挥的功能非常类似,只是虚拟机栈为虚拟机执行java方法而服务,而本地方法栈为虚拟机执行native方法而服务。与虚拟机栈一样,本地方法栈也会抛出 StackOverflowError OutOfMemoryError异常。任何本地方法接口都会使用某种本地方法栈。当虚拟机调用java方法时,虚拟机会创建一个栈帧并且压入虚拟机栈;当虚拟机调用本地(native)方法时,虚拟机不会创建新的栈帧,虚拟机栈会保持不变,虚拟机只是简单的动态连接并直接调用相关的本地方法。     

方法区(Method Area):方法区在JVM中也是一个非常重要的区域,它与堆一样,是被线程共享的区域。在方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。在方法区中有一个非常重要的部分就是运行时常量池,它是每一个类或接口的常量池的运行时表示形式,在类和接口被加载到JVM后,对应的运行时常量池就被创建出来。当然并非Class文件常量池中的内容才能进入运行时常量池,在运行期间也可将新的常量放入运行时常量池中,比如Stringintern方法。       

(Heap Memory):堆数据区是用来存放对象和数组(特殊的对象)。堆内存由多个线程共享。堆内存随着JVM启动而创建。众所周知,Java中有一个很好的特性就是自动垃圾回收。垃圾回收就操作这个数据区来回收对象进而释放内存。如果堆内存剩余的内存不足以满足于对象创建,JVM会抛出OutOfMemoryError错误。

 

 

JVM结构 1.类加载器 2.执行引擎 3.内存区 4.本地方法接口(主要是调用C或C++实现的本地方法及返回结果)

GC的主要任务: 1.分配内存; 2.确保被引用对象的内存不被错误的回收; 3.回收不再被引用的对象的内存空间 垃圾回收机制的主要解决问题 1.哪些内存需要回收?

针对问题一,垃圾收集器会对堆进行回收前,确定对象中哪些是“存活”,哪些是”死亡“

1.引用计数算法 2.可达性分析算法

2.什么时候回收?

即使是被判断不可达的对象,也要再进行筛选,当对象没有覆盖finalize()方法,或者finalize方法已经被虚拟机调用过,则没有必要执行;
如果有必要执行——放置在F-Queue的队列中——Finalizer线程执行。

3.如何回收?

垃圾收集算法: 1.标记—清除算法 两个阶段:标记,清除; 不足:效率问题;空间问题(会产生大量不连续的内存碎片)

2.复制算法 将可用内存按容量分为大小相等的两块,每次都只使用其中一块; 不足:将内存缩小为了原来的一半 新生代

3.标记—整理算法 标记,清除(让存活的对象都向一端移动) 老年代

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HotSpot的垃圾回收机制采用分代回收,堆分为年轻代和老年代,非堆就是持久带。面对不同的代,采用不同的回收策略。 而年轻代又可以分为1个Eden和2个Survivor。对于Eden,大多数对象都是先在此区域开辟空间,存储年轻对象的实例数据。Eden相对于Old带,空间是比较小的。所以对象数据不断地在此开辟空间,Eden不够了,年轻代发生了回收。放置(稍后会说怎么放置)到S1或者S2。S1或者S2不够放了,直接放到Old带。根据年轻代的特点,空间小,发生回收事件频率较高,那么就采用标记-复制的算法将Eden中的对象实例数据克隆到S1或者S2或者直接克隆到Old带。标记-复制算法优点是:快速、节省内存碎片。缺点是:内存消耗的空间需要变为原来的50%,另一块空间作为复制的目标。 老年代因为空间比较大,存储的对象又是比较长寿的对象,所以采用标记-整理或者也称作标记-压缩算法。这样不必开辟另外50%的空间用于复制目标,也不用担心这个较为辽阔的内存空间产生占用碎片的问题。缺点就是又标记、又压缩的。对于Old带比较费时间。 持久带虽然资料上没有明说,但是根据持久带的作用和特点以及触发该区回收的情景可以推算,持久带采用的回收算法应该是标记-整理/压缩算法JVM内存回收只要是针对这3个区域来说的。像NIO的直接文件内存读取,使用的是直接内存,只有出发了FullGC方能回收该区域!JNI调用本地库,本地代码所消耗的内存需要操作系统额外开辟内存

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值