zoukankan      html  css  js  c++  java
  • jvm GC基础

    优秀博文转自:https://blog.csdn.net/qq_33048603/article/details/52727991

    了解一下JVM内存运行时数据区的三个重要的地方

    • 堆(heap) : 他是最大的一块区域,用于存放对象实例和数组,是全局共享的.
    • 栈(stack) : 全称为虚拟机栈,主要存储基本数据类型,以及对象的引用,私有线程
    • 方法区(Method Area) : 在class被加载后的一些信息 如常量,静态常量这些被放在这里,在Hotspot里面我们将它称之为永生代

    我们知道对象的实例是存在于逻辑堆中,而GC在逻辑堆是怎样运行的呢,下面我们看下逻辑堆的具体结构 
    这里写图片描述 
    就像上面的图可以看出 逻辑堆分为 年轻代与年老代,对于非堆内存这里先不讲解,而年轻代则被分为 eden survivor1 survivor2 ,对于一个新被实例化的对象都是存在于年轻代中的eden区,按照GC的运行机制,会回收掉已经死掉的对象,而对象一般都是在年轻代就会死去,所以年轻代比老年代需要更频繁的GC清理,下面针对年轻代与老年代的回收机制有不同的讲解

    年轻代 :

    在年轻代中jvm使用的是Mark-copy算法,就像算法名字说的那样有两个步骤,第一是标记(Mark) 第二是copy(复制),Mark主要用于标记出还活着的实例,然后清除掉没有被标记的实例,释放内存,然后Copy部分则是将还活着的实例根据年龄拷贝到不同的年龄代,而jvm又是根据什么来区分年龄代,和实例存活与不存活的呢? 下面将对这个过程进行讲解


    对于标记 与区分年龄代的技术 我们一般都是用到的都是引用计数器,在每一个对象中都含有引用计数器,都有引用指向对象的时候 引用计数器就会加1,不在被引用 计数器 减 1,对与垃圾回收的策略则是标记所有活着的实例,将没有被标记的实例全部回收 释放内存,


    对于静态,我们都知道静态方法与静态变量是不会产生实例的,直接通过类的引用,使用 ClassLoader进行加载的类数据如前面所说是不存在逻辑堆里面的,直接存在于永生代里面也就是 方法区里面,这个类一旦被清除掉里面所有的静态变量都会被清除

    当我们在 Object obj 的时候 向逻辑堆中的 Eden区域 申请内存,当Eden区域的内存不足的时候,这个时候会触发GC这个时候称gc为小型垃圾回收,每个实例都有一个独有的年龄,每个引用被经历过一次GC后就会年龄加一,同时就会将没有被清理掉的对象全都copy到上图的survivor1区域,如图1所示: 
    这里写图片描述 
    当第二次GC执行的时候就会使用Mark算法找到存活的对象,然后将他们的年龄加1,并且将他们拷贝到survivor2区域,然后执行GC,这样就可以实现survivor1 与 survivor2 两个一样大的区域进行交替使用,当对象的年龄足够大的时候,对象就会被移动到老年代,这里移动到老年代的标准由JVM的参数所决定

  • 相关阅读:
    JavaScript | 闭包
    Photoshop | 快速抠头发(调整边缘/选择并遮住)
    JavaScript | 基础表单验证(纯Js)
    JavaScript | 事件
    JavaScript | 数组
    JavaScript | 对象与属性
    JavaScript | 基础(变量/引用/转换/函数)
    Altium Designer 10 | 常用库及部分元件名中英文对照表
    电路 | 基本概念
    读点什么 |《把时间当作朋友》李笑来
  • 原文地址:https://www.cnblogs.com/shuaishuai1993/p/8650688.html
Copyright © 2011-2022 走看看