铁锅炖大鹅本网站主要是在生活上、学习上、工作上的个人分享!返回首页

JVM

java文件通过javac命令编译成class文件,java运行class文件。通过类加载器加载到JVM中,通过运行时数据区运算,再通过执行引擎调用本地库接口,实现跨平台运行。

共享内存:堆和方法区

私有内存:线程栈、本地方法栈、程序计数器

堆主要存储对象实例(全局变量作为对象的一部分也存储在堆中)

方法区主要存储类信息、静态变量、常量

线程栈主要存储方法、成员变量

线程栈主要包含栈帧,栈帧包含成员变量表、操作数栈、动态链接、方法出口

本地方法栈主要存储native方法

堆 主要是由新生代和老年代组成 新生代由8Eden:1Survivor0:1Survivor1组成

GC垃圾回收:minor gc和full gc都需要停止所有用户线程STW(Stop The World)

对象被判定为垃圾的标准:对象没有被其他对象引用

什么方法去判断对象没有被其他对象引用?引用计数算法,被引用时+1,完成引用-1,0时被回收,执行效率高,无法检测循环引用的情况,导致内存泄漏;可达性分析算法,通过判断对象的引用链是否可达来决定对象是否可以被回收,从GCRoot开始遍历。

什么时候触发GC:当对象所在堆内存区域满时就会触发。

默认新生代区域的对象的分代年龄达到15时就会把该对象放到老年代区域里。

GCRoot:线程栈的成员变量,静态变量等

通过以GCRoot为根节点,对根节点开始向下一步一步的引用的(堆Eden内存中的)对象标记为非垃圾对象,并把这些对象放到Survivor区中,Eden中剩余的则为垃圾对象,并对其进行垃圾回收。

垃圾回收算法

标记-清除算法,对存活的对象进行扫描并标记,回收不可达对象。缺点造成内存碎片,导致内存不连续。

(老年代)标记-整理算法,对存活的对象进行扫描并标记,将可达与不可达对象进行分类移动,再回收不可达对象。避免产生内存碎片,回收后的内存连续。适用存活率高的对象。

(新生代)复制算法,按比例分配两块内存,一块存储对象,一块空闲,当存储对象的内存用完时将对象面存活的对象复制到空闲面,再将对象面清空。适用存活率低的对象,浪费内存空间。

分代收集算法,按照对象生命周期的不同划分区域,采用不用的垃圾回收算法,(新生代)复制算法,(老年代)标记-整理算法。

年轻代的某一时刻只有S0区域或S1区域被使用

年轻代的某一时刻只有Eden+S0区或Eden+S1区域被使用

Eden+S0复制非垃圾对象至S1

Eden+S1复制非垃圾对象至S0

当非垃圾对象超过S0或S1的可配置比例时就会直接放到老年代。

老年代区域存在大量回收不了的对象会发生OOM内存溢出的问题

GC分类:

(1)Minor GC:年轻代的垃圾收集动作,采用复制算法。新的对象会分配到Eden区,当Eden区或S0区或S1区满时触发垃圾回收时,会把Eden区和S0区和S1区标记为非垃圾对象复制到S0或S1中,再把剩余的对象全部清空。

(2)Full GC:年轻代和老年代的垃圾收集动作,采用标记-整理算法。当老年代满时触发。

Full GC的速度比Minor GC慢,但执行频率低。

minor gc扫描对象时候和full gc类似,只不过当遍历的对象是old区的对象就停止进一步遍历了,这样就跳过了所有old对象扫描,扫描数量大大减少(只是young区的),就是如果young区的某个对象只被old应用,那么该对象就扫描不到成了需要被回收的。这时候Dirty cards 排上了用场,dirty card 里面记录了old 区所有引用了young 区的对象,所以扫描

一次dirty card问题就解决了。


网站备案号 京ICP备2021001624号-1

京公网安备 11011202002596号