JAVA JVM

作者: 折剑游侠 | 来源:发表于2020-04-29 16:25 被阅读0次

JVM内存区域

  • 程序计数器--->当前线程所执行的字节码位置指示器。
  • 虚拟机栈--->描述的Java方法执行的内存模型,每个方法在执行的同时会创建一个栈帧,存储着局部变量、操作数栈、动态链接和方法出口等。
  • 本地方法栈--->本地方法执行的内存模型。
  • 堆--->所有对象实例分配的区域。
  • 方法区--->所有已经被虚拟机加载的类的信息、常量、静态变量和即时编辑器编译后的代码数据。

其中程序计数器、虚拟机栈、本地方法栈为线程私有;堆、方法区为线程共享。

JVM内存模型

  • 所有变量的内存都需要存储在主内存。
  • 每个线程都有自己的工作内存,线程中使用的所有变量以及对变量的操作都基于工作内存,工作内存中的所有变量都是从主内存读取过来的。
  • 不同线程间的工作内存无法直接交流,必须通过主内存完成。

GC

1. 可回收对象

判断对象是否可以回收常用的两种方法:引用计数和可达分析

  • 引用计数:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。
  • 可达性分析:从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

GC Roots:

  • 虚拟机栈中引用的对象。
  • 方法区中类静态属性实体引用的对象。
  • 方法区中常量引用的对象。
  • 本地方法栈中JNI引用的对象。
2. 触发时机
  • 调用System.gc触发
  • 系统自身来决定GC触发的时机(根据Eden区和From Space区的内存大小来决定。当内存大小不足时,则会启动GC线程并停止应用线程)

GC又分为 minor GC 和 Full GC

  • minor GC:频率高、针对新生代。
  • Full GC:频率低、发生在老年代、通常会伴随一次Minar GC、速度慢。
3.GC常用算法
  • 标记 - 清除:首先标记出需要回收的对象,标记完成后统一回收所有被标记的对象。容易产生碎片空间。
  • 复制算法:它将可用的内存分为两块,每次只用其中的一块,当需要内存回收的时候,将存活的对象复制到另一块内存,然后将当前已经使用的内存一次性回收掉。需要浪费一半的内存。
  • 标记 - 整理:让存活的对象向一端移动,之后清除边界外的内存。
  • 分代搜集:根据对象存活的周期,Java堆会被分为新生代和老年代,根据不同年代的特性,选择合适的GC收集算法。

JAVA对象创建过程

  • 检查类是否被加载
  • 为新生对象分配内存
  • 初始化零值
  • 进行必要设置
  • 执行init方法

JAVA类加载过程

  • 加载:将类的全限定名转化为二进制流,再将二进制流转化为方法区中的类型信息,从而生成一个Class对象。
  • 验证:对类的验证,包括格式、字节码、属性等。
  • 准备:为类变量分配内存并设置初始值。
  • 解析:将常量池的符号引用转化为直接引用。
  • 初始化:执行类中定义的Java程序代码,包括类变量的赋值动作和构造函数的赋值。
  • 使用
  • 卸载

JAVA类加载机制

  • 双亲委派:双亲委派模式要求除了顶层的启动类加载器之外,其余的类加载器都应该有自己的父类加载器,双亲委派模式中采用组合关系来复用父类加载器的相关代码。
  • 类加载器任务来临,先交给父类加载器处理,如果父类加载器还存在父类加载器,进一步向上委托,直到顶层启动类加载器为止。父类完成加载任务则成功返回;父类加载器无法完成任务,子类加载器才会尝试自己加载。
  • 好处是可以避免类的重复加载

JAVA四种引用类型

  • 强引用:代码中直接使用关键字new的对象即为强引用。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError使程序异常终止,也不会回收。
  • 软引用(SoftReference):内存空间不足才会回收。
  • 弱引用(WeakReference):GC发生时,无论内存空间是否充足,都会回收。
  • 虚引用:通常用来在GC前收到一个系统通知。

相关文章

网友评论

    本文标题:JAVA JVM

    本文链接:https://www.haomeiwen.com/subject/rftnwhtx.html