当前位置:网站首页 > Java基础 > 正文

java算法基础面试



前言

垃圾回收是Java实现动态内存管理的重要手段。

JVM内存模型

JVM内存模型.jpg

JVM将虚拟机分为5大区域:

  • 程序计数器:线程私有的,是一块很小的内存空间,作为当前线程的行号指示器,用于记录当前虚拟机正在执行的线程指令地址;
  • 虚拟机栈:线程私有的,每个方法执行的时候都会创建一个栈帧,用于存储局部变量表、操作数、动态链接和方法返回等信息,当线程请求的栈深度超过了虚拟机允许的最大深度时,就会抛出StackOverFlowError;
  • 本地方法栈:线程私有的,保存的是native方法的信息,当一个jvm创建的线程调用native方法后,jvm不会在虚拟机栈中为该线程创建栈帧,而是简单的动态链接并直接调用该方法;
  • JAVA堆:java堆是所有线程共享的一块内存,一般也是最大的,几乎所有对象的实例和数组都要在堆上分配内存,因此该区域经常发生垃圾回收的操作;
  • 方法区:存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码数据。即永久代,在jdk1.8中不存在方法区了,被元数据区替代(原方法区被分成两部分;1:加载的类信息,2:运行时常量池);

垃圾回收

垃圾回收一般发生在JAVA堆区域。JAVA堆可以细分为新生代老年代。新生代又被细分为Eden和Survivor(S0+S1),默认的分配比例为8:1:1。

当Eden区满时,会触发一次Minor GC(夭折?),存活下来的对象会被分到Survivor区,但是大对象(需要大量连续内存空间的对象)会被直接分到老年代。从Eden出生的对象,每经历一次Minor GC,年龄+1,到15被分配到老年代。

当老年代满了,而无法容纳更多对象的话,会触发一次FULL GC。FULL GC的对象是整个内存堆(年轻代和老年代)。Major GC是发生在老年代的GC,清理老年区,经常会伴随至少一次Minor GC。

对象存活判断

  • 引用计数法
    为每个对象设置一个引用计数器,每被引用+1,引用失效-1,当计数为0,等待回收。但是存在循环引用的问题,一般主流虚拟机不采用该方法。
  • 可达性分析法
    从GC Roots向下搜索,不可达的对象,说明不可用,经过2次不可达标记后被正式回收。第一次,判断是否有执行finalize()的必要(是否执行过finalize,是否覆盖了finalize()[重写且不为空]),若无必要,等待回收,若有必要,将被放入F-Queue队列,生成一个finalize线程执行该方法,之后进行第二次GC标记,若依然不可达GC Roots,将被回收。

note*

  • finalize线程不能保证该方法一定被执行,因为如果线程执行缓慢或进入了死锁,会导致回收系统的崩溃。
  • 可以作为GC Roots的对象:虚拟机栈中引用的对象、方法区类静态属性引用的变量、方法区常量池引用的对象、本地方法栈JNI引用的对象

垃圾回收算法

  • 标记清除算法
    第一步,利用可达性进行存活和垃圾对象标记;
    第二步,遍历,将标记为垃圾的对象回收;
    特点:效率低,标记和清除的效率都不高;标记和清除后会产生大量的不连续的空间分片,可能会导致之后程序运行的时候需分配java算法基础面试大对象而找不到连续分片而不得不触发一次GC。
  • 标记整理算法
    第一步:利用可达性进行存活和垃圾对象标记;
    第二步:将所有的存活的对象向一端移动,将端边界以外的对象都回收掉;
    特点:适用于存活对象多,垃圾少的情况;需要整理的过程,无空间碎片产生。
  • 复制算法
    将内存按照容量大小分为大小相等的两块,每次只使用一块,当一块使用完了,就将还存活的对象移到另一块上,然后在把使用过的内存空间移除;
    特点:不会产生空间碎片;内存使用率极低。
  • 分代收集算法
    根据内存对象的存活周期不同,将内存划分成几块,java虚拟机一般将内存分成新生代和老年代,在新生代中,有大量对象死去和少量对象存活,所以采用复制算法,只需要付出少量存活对象的复制成本就可以完成收集;老年代中因为对象的存活率极高,没有额外的空间对他进行分配担保,所以采用标记清理或者标记整理算法进行回收;

垃圾回收器

垃圾回收器主要分为以下几种:Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1;

  • Serial:
    单线程的收集器,收集垃圾时,必须stop the world,复制算法。
  • ParNew:
    Serial收集器的多线程版本,也需要stop the world,复制算法.
  • Parallel Scavenge:
    新生代收集器,复制算法的收集器,并发的多线程收集器,目标是达到一个可控的吞吐量,和ParNew的最大区别是GC自动调节策略;虚拟机会根据系统的运行状态收集性能监控信息,动态设置这些参数,以提供最优停顿时间和最高的吞吐量;
  • Serial Old
    Serial收集器的老年代版本,单线程收集器,使用标记整理算法。
  • Parallel Old
    是Parallel Scavenge收集器的老年代版本,使用多线程,标记-整理算法。
  • CMS:
    是一种以获得最短回收停顿时间为目标的收集器,标记清除算法,运作过程:初始标记,并发标记,重新标记,并发清除,收集结束会产生大量空间碎片;
  • G1:
    标记整理算法实现,运作流程主要包括以下:初始标记,并发标记,最终标记,筛选回收。不会产生空间碎片,可以精确地控制停顿;
    G1将整个堆分为大小相等的多个Region(区域),G1跟踪每个区域的垃圾大小,在后台维护一个优先级列表,每次根据允许的收集时间,优先回收价值最大的区域,已达到在有限时间内获取尽可能高的回收效率;

参考文章

版权声明


相关文章:

  • java基础深入2025-04-04 16:50:05
  • java基础最重要2025-04-04 16:50:05
  • 基础语言基础java书2025-04-04 16:50:05
  • java基础框架有哪些2025-04-04 16:50:05
  • java转型基础2025-04-04 16:50:05
  • java程序设计基础第四版课后答案2025-04-04 16:50:05
  • java 基础术语2025-04-04 16:50:05
  • java语言基础心得2025-04-04 16:50:05
  • java语言程序设计第八版基础篇课后答案2025-04-04 16:50:05
  • java对象基础2025-04-04 16:50:05