java jvmGC

我们都知道java是依靠jvm进行跨平台的,具体流程是

.java文件→编译器(javac)→.class字节码文件→解释器→运行

这其中将字节码解释成对应平台的执行集的工作就是交给jvm,这样我们只需要专注写代码,jvm帮我们将操作系统和硬件都隔离开了,所以说,我们为了写的代码都是运行在jvm上的,内存操作也都是通过jvm的,所以我们今天要谈的垃圾回收就要通过jvm来讲。

一、jvm内存结构

        垃圾回收其实就是对jvm内存中无用的对象进行删除,其中jvm运行时内存主要分为5块

它们分别是:程序计数器,虚拟机栈,本机方法栈,堆区,方法区。其中前三个是每个线程私有的,所以它们会随着线程的关闭而删除,不需要进行管理,堆区和方法区不会随着线程关闭而删除需要管理,我们主要的gc就是针对它们

二、回收算法

一般来说我们需要gc就需要判断对象是否是垃圾,我们有两种算法来判断

一是引用技术法:

        php中是用的这种算法,原理是:为每一个对象分配一个计数器,当这个对象被另一个对象引用时,这个计数器就加一;当被另一个对象取消引用时,计数器就减一。当这个计数器的值为零时,就表示当前对象没有被任何对象所引用,那么这个对象就可以被垃圾回收器进行回收了。不过这种算法有个致命的缺点就是循环引用(a和b互相引用)时会造成内存泄漏

二是可达性分析算法:

        思路是:将一系列被称之为“GC Roots”的根对象作为起始节点,从这个根节点出发,通过引用关系向下寻找它可以到达的对象,寻找过程中经过的路线称之为引用链,一个系统中可以有多个根节点,也就是说 GC Roots 是一个节点的集合。如果一个对象无法通过任何一个 GC Roots 根节点找到,即 0 条引用链,那么这个对象就不是存活对象了,后面在进行垃圾回收时,可以被垃圾收集器回收。

缺点是执行算法的时候会暂停所有的线程,因为需要防止线程修改引用链

能作为“GC Roots”的对象包括以下几种:

  • 虚拟机栈(栈帧中的本地变量表)中的引用的对象。
  • 方法区中的类静态属性引用的对象。
  • 方法区中的常量引用的对象。
  • 本地方法栈中JNI(即一般说的Native方法)的引用的对象。

三、堆区内存结构

        我们有了回收算法来判断标记哪些对象可以删除,但是具体是怎么个流程呢,这样我们就要知道主要的堆的结构了,现在主流都是把堆分为三块,年轻代,老年代,永久代(元空间)

1.年轻代

        年轻代一般分为三块 eden(伊甸园区),survivorfrom(幸存区1),survivorto(幸存区2),大小比例默认8:1:1。新生代用于储存那些新建的对象,eden满了后将触发minor GC 用于清理年轻代这时候将eden区与from区剩余的对象复制到to区 然后删除from区,然后to区变成from区如果to区内存不够这直接存入老年代,还有to与from去反复15次后对象还在(每次翻转对象引用加一)则将对象 移至老年代

2.老年代

        老年代一般存长期存活和大的对象,老年代满了后会触发full gc

Full GC是清理整个堆空间,包括年轻代和老年代。如果Full GC之后,堆中仍然无法存储对象,就会抛出OutOfMemoryError异常。

堆有关的参数

3.永久代(元空间、方法区)

        方法区同 Java 堆一样是被所有线程共享的区间,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码。更具体的说,静态变量+常量+类信息(版本、方法、字段等)+运行时常量池存在方法区中。常量池是方法区的一部分

          1.7之前叫永久代,1.8后叫元空间,元空间在本地硬盘里

元空间两个参数:

  1.  MetaSpaceSize:初始化元空间大小,控制发生GC阈值
  2.  MaxMetaspaceSize : 限制元空间大小上限,防止异常占用过多物理内存

 

 

 差不多上面介绍了gc的回收及堆的结构

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值