• 面试:内存划分及GC算法与种类


    一、JVM内存划分

    线程独占区---是线程安全

    1、程序计数器

    • 相当于一个执行代码的指示器,用来确认下一行执行的地址
    • 每个线程都有一个
    • 没有 OOM 的区

    2、虚拟机栈

    • 我们平时说的栈就是这块区域
    • java 虚拟机规范中定义了 OutOfMemeory , stackoverflow 异常

    3、本地方法栈

    • java 虚拟机规范中定义了 OutOfMemory ,stackoverflow 异常

    线程共享区---是线程不安全

    1、方法区

    • ClassLoader 加载类信息
    • 常量、静态变量
    • 编译后的代码
    • 会出现 OOM
    • 运行时常量池
      • public static final
      • 符号引用类、接口全名、方法名

    2、java 堆 (需要优化的地方)

    • 虚拟机能管理的最大的一块内存 GC 主战场
    • 会出现 OOM
    • 对象实例
    • 数据的内容

    Q:一个进程中有几个堆,几个栈?

    由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
    所以说,一个进程里面有多个线程,因此有多个栈,但是所有栈共享一个堆
    一个堆,多个栈

    二、JAVA GC 如何确定内存回收

    目前虚拟机基本都是采用可达性分析算法

    GC Roots 的对象作为起始点,向下搜索走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链,即从GC roots 到这个对象不可达,则证明对象不可用,可被回收。

    可以作为 GC Roots 的对象

    • 虚拟机栈正在运行使用的引用
    • 静态属性 常量
    • JNI 引用的对象

    三、垃圾收集器算法

    在根搜索算法的基础上垃圾收集器算法主要有三种:标记-清除法, 复制算法(新生代的GC),标记-整理算法(老年代GC)。

    1. 标记-清除法

    分为两个阶段:标记阶段和清除阶段。在标记阶段,通过根节点,标记所有从根节点开始的可达对象,因此没有被标记的就是没有被引用的垃圾对象,然后在清除阶段,清除所有没有被标记的对象。

    缺点:(1)效率低,使用递归与全堆对象遍历/还要停止程序,如果在交互式程序上体现,用户体验会很糟糕(2)这种清理出来的内存空间是不连续的,这样内存的布局就会乱七八糟

    2. 复制算法(新生代的GC)

    将原有的内存空间分成两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中存活的对象复制到未使用的内存中,之后清除正在使用内存块中的所有对象,然后交换两个内存块的角色,完成垃圾回收。与标记-清除法相比,复制算法更为高效。但是并不适用于存活较多的场合,比如老年代。

    将内存分为一块比较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中一块Survivor。当回收时,将Eden和Survivor中还存活着的对象一次性地复制到另外一块Survivor空间上,最后清理掉Eden和刚才用过的Survivor空间。HotSpot虚拟机默认Eden和Survivor的大小比例是8:1,也就是说,每次新生代中可用内存空间为整个新生代容量的90%(80%+10%),只有10%的空间会被浪费。
    3. 标记-整理算法(老年代GC)

    标记完后将所有的存活对象压缩到内存的一端,之后在清理边界外所有的垃圾对象。

    标记/整理算法不仅可以弥补标记/清除算法当中,内存区域分散的缺点,也消除了复制算法当中,内存减半的高额代价。
    但是,标记/整理算法唯一的缺点就是效率也不高。

    分代收集算法(新生代+老年代GC)

    概念:根据对象的存活周期将Java堆分为新生代和老年代,短命对象归为新生代,长命对象归为老年代。

    • 少量对象存活,适合复制算法:在新生代中,每次GC时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成GC。
    • 大量对象存活,适合用标记-清理/标记-整理:在老年代中,因为对象存活率高、没有额外空间对他进行分配担保,就必须使用“标记-清理”/“标记-整理”算法进行GC。
  • 相关阅读:
    【注解和反射】性能分析
    HTML&CSS&HTTP
    B. Comparison String
    Servlet---从创建项目到部署项目的整个流程
    【C++】string类的使用,小试牛刀
    【C语言入门】ZZULIOJ 1000~1010
    记LGSVL Map Annotation(3)利用map annotation生成一个十字路口的opendrive格式地图
    Pico neo3+Unity开发记录
    如何优雅的配置 Java 微服务
    探索数字化节能降碳 广域铭岛助力电解铝行业碳达峰
  • 原文地址:https://blog.csdn.net/cpcpcp123/article/details/127938996