Java之JVM

1,126 阅读4分钟

JVM是什么

JVM包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域,他屏蔽了底层的操作系统技术,让我们的java程序生成了在java虚拟上的字节码文件(.class),因此java可以跨平台使用。

JVM有什么

PC寄存器

存储了每个线程下一步要做的事情

JVM栈

JVM栈是线程私有的,每个线程都会创建JVM栈,栈里存放了局部基本类型的变量(int等)。

存储里所有对象

  • 堆内存都是线程共享的,因此每次申请对象都需要申请锁资源,在线程上增加了TLAB,相当于线程缓存区,因此每个线程申请资源时,都会先申请自身线程的资源。
  • 新创建的对象基本都会存在于新生代区域,除了对象足够大。活的够久的对象会被存放在老年代。

运行时常量池

存储了运行中的常量信息、方法和field的引用信息。

方法区域

存储了类的信息,静态变量、静态常量、类中的方法信息等,一定条件下也会被gc的。

本地方法堆栈

存放了运行时的方法的调用状态

垃圾回收

判断对象是否可用的两种常用方法

引用计数算法:给对象中添加一个引用计数器,当一个地方引用了该对象,计数器加1,当一个地方没有引用该对象,计数器减1

根对象可达法:从根对象向下遍历,当无法遍历到则证明该对象无法被引用。

垃圾收集算法

  • 标记-清除法:分为标记和清除两个阶段,将对象标记后进行清除

image.png

优点: 算法简单

缺点: 清楚后会留下大量的内存碎片

  • 复制算法: 将一块内存分为A和B两块区域,只有一片区域负责内存的存储,当需要清理时,将所有不需要清除的对象复制到另一片区域,清理之前的空间。

image.png 优点:不会留下内存碎片 缺点:内存空间利用率过低

  • 标记-整理算法 : 将所有需要清除的对象清除后,将剩余的对象向一侧移动。

image.png

优点: 解决了内存碎片的问题 缺点:移动麻烦

  • 分代收集算法

这种是目前java常用的垃圾收集算法

根据对象特性将对象分为新生代和老年代和元空间(方法区-持久代)(在新的版本中已经将永久代废弃,引入了元空间的概念,永久代使用的是JVM内存而元空间直接使用物理内存)

因此我们可以根据不同的方法对对象进行处理。

image.png

新生代 : 分为Eden:Survivor from : Survivor to = 8:1:1 ,由于新生代的对象生命周期很短,所以新生代采用复制算法。

老年代 : 老年代的对象由于存活周期长,一般使用标记清除或者标记整理算法

新生代的对象会先去Eden区,当Eden区满了会去Survivor from区,当两个区域都满了后会进行一次Minor GC,将Eden和Survivor from copy到Survivor to区,再清空Eden区和Survivor from区域,这时候 from区会变为to 区,如果Survivor from区无法容纳全部的对象,则会根据老年代的分配担保策略存入老年代,如果老年代也无法容纳则会进行full GC。

什么时候进入到老年代

1、根据参数,大对象直接进入老年代。 2、长期存活的对象进入老年代:每一个对象刚创建时都会有一个年龄,每次minorGC 都会给年龄加1,默认到达15岁则升级为老年代,如果Survivor去区中相同年龄所有对象大小的总和大于Survivor区的一半,则大于等于这个年龄的对象会晋升至老年代。

  • 对新生代的对象回收称为minorgc
  • 对老年代的对象进行回收称为full gc
  • 主动gc为full gc

JVM 也会根据不同的对象进行不同的回收策略

  • 强引用 : 默认使用这种引用。当对象没被引用时才会回收这种对象
  • 软引用 : 当内存不够时会被回收
  • 弱引用 : 当gc时一定会被回收
  • 虚引用 : 用于引用只是用来得知对象是否gc