JVM之运行时数据区

目录

程序计数器

Java虚拟机栈

本地方法栈

方法区

问题:

什么时候进行垃圾回收?

哪些内存需要回收?

哪些对象可以进入老年代?

垃圾回收算法


Java运行时数据区结构如下:

存储数据:堆和方法区

存储指令:程序计数器、虚拟机栈、本地方法栈

程序计数器

线程私有。

作用:记录当前线程所执行字节码的行号。

原因:在多线程情况下,由于是采用时间片轮转的执行方式,一次只能执行一个线程,因此需要记录上一个线程的行号,保护现场,以便恢复执行。在执行的方法是Java方法时是程序计数器中保存的是行号,在执行的是本地方法(底层C、C++),程序计数器的值是undefined。PC寄存器也是唯一的没有定义任何异常的内存空间。

Java虚拟机栈

可以使用XSS设置虚拟机栈的大小。

线程私有,每一个线程启动时都会创建一个Java虚拟机栈,生命周期和线程相同。

作用:先进后出的数据结构,存储当前线程运行方法时所需要的数据、指令及返回地址。

执行方法的过程就是栈帧入栈和出栈的过程,运行方法时会创建一个栈帧进行入栈,当方法执行结束时又会出栈。当入栈的深度超过规定时(-XSS可以指定深度),就会抛出StackOverFlow异常,特别注意递归的调用。

栈帧的结构:局部变量表、操作数栈等。

局部变量表:用来存放方法中的局部变量和对象引用。

局部变量表的特点:①局部变量表的第一个数据是this引用。②局部变量表中的大小是在编译时就已经确定了的,局部变量越多的话,入栈的栈帧数量就会更少,即递归的次数就越少。③局部变量表中的槽位可以复用,当某个局部变量的作用域失效时,新的局部变量可以复用失效数据的槽位,而不必占用新的槽位,达到节省资源的目的。④局部变量表的访问方式是通过索引。

   操作数栈:是Java虚拟机的工作空间,通常用于存储计算的中间变量,通过压栈和出栈操作访问。当需要计算数据时,首先从局部变量表中取出两个数据依次进入操作数栈,之后依次弹栈进行相加运算,再将结果压入操作数栈。之后弹出结果,将结果保存在局部变量表中。

本地方法栈

   执行本地方法,结构与虚拟机栈相同。

使用xms、xmx可以设置堆空间的大小

线程共享的区域。主要用来存储对象。

堆分为新生代和老年代,新生代与老年代的比例为1:2(-XX:NewRatio可以设置),即新生代占1/3的堆空间大小,老年代占用2/3的堆空间大小。其中新生代又分为1个Eden区和2个survivor区(from和to)比例为eden:from:to=8:1:1(可以通过-XX:SurvivorRatio来设定)。新生代实际可用的内存空间为90%,因为总有一块from或者to区域为空。当new一个对象时,对象首先分配在Eden,当Eden区的内存空间不足时,会进行一次MinorGC,要是Eden的对象还存活,它会被移动到其中的某个survior区(由于采用复制回收算法),每次经过一次GC,对象还存活,将它的年龄加1,默认到达15次之后,该对象会从新生代进入老年代。大对象(数组等)直接在分配时就进入老年代。当老年代内存不足的时候会进行一次FullGC,其中的一次FullGC也会伴随着一次MinorGC。

方法区

   线程共享的区域,保存类的信息、静态变量、常量池等。

问题:

什么时候进行垃圾回收?

当新生代或老年代在分配对象内存空间不足时,进行GC。

哪些内存需要回收?

根搜索算法判断对象不可达时就要进行回收。对象不可达:①从根开始没有到达该对象的引用②没有覆盖finallize方法或者已经执行过finallize方法,确认对象没有被复活。可以将这些内存空间回收。

哪些对象可以进入老年代?

  • GC次数超多15次的对象可以晋升到老年代
  • 大对象直接可以进入老年代

新生代和老年代的算法?

新生代采用复制算法,老年代采用标记回收算法。

1个Eden区和2个survivor区,每次只用Eden区和其中的一个survivor区,当要回收内存时,会将正在使用的Eden区和from区的存活对象,复制到另一个to区中,之后将Eden和from区全部清除,当前工作内存设置位to。

新生代特点:对象生命周期短,存活对象少采用复制算法,性价比高。

老年代大多是存活对象,因此采用标记清除或者标记压缩,将存活的对象进行标记,未存活的对象进行回收。这种性价比高。

垃圾回收算法:

  1. 引用计数法 缺点:无法解决互相引用
  2. 标记清除法 缺点:内存碎片
  3. 复制算法 缺点:内存减小了一半
  4. 标记压缩法 即解决了内存碎片又解决了内存减半
  5. 分代回收算法 新生代(复制)老年代(标记清除)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值