深入理解Java虚拟机

0 阅读4分钟

一、Java简介

先了解一些基础概念:

  • JDK(Java Development Kit):Java程序设计语言 + Java虚拟机 + Java API类库
  • JRE(Java Runtime Environment):Java API类库中的Java SE API子集 + Java虚拟机

Java构成基础工具:java、javac、javadoc、apt、jar、javap、JPDA、JConsole、Java VisualVm

Java技术体系(按平台划分)

  • Java Card:支持小型程序(applet),运行在小内存设备(如智能卡)的平台。
  • Java ME(Micro Edition),旧称J2ME:包含Java API精简集,针对移动终端支持的平台。
  • Java SE(Standard Edition),旧称J2SE:提供完整Java核心API,支持桌面应用(如Windows桌面应用)的平台。
  • Java EE(Enterprise Edition),旧称J2EE:支持使用多层架构的企业应用(如ERP、CRM)的Java平台,包含Java SE API及大量扩展。

Java的语言特性

  • 支持模块化开发与部署
  • 支持混合语言开发(基于JVM实现)
  • 支持多核并行
  • 丰富的语法特性(1.5后:自动装箱、泛型、动态注解、枚举、可变长参数、遍历循环等)
  • 支持64位CPU架构

二、自动内存管理机制

image.png

Java运行时数据区

  • 程序计数器:线程所执行字节码的行号指示器,每个线程独立,用于分支、循环、跳转、异常处理、线程恢复等。
  • 虚拟机栈:Java方法执行的内存模型(每个方法从调用到完成对应一个栈帧的入栈到出栈),线程私有,生命周期与线程相同。栈帧包含局部变量表、操作栈、动态链接、方法出口等。
  • 本地方法栈:与虚拟机栈类似,为Native方法服务。
  • Java堆(GC堆):几乎所有对象实例分配内存的地方,线程共享。
  • 方法区(非堆):存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等,线程共享。包含运行时常量池。

容易忽视的内存泄露原因:某些对象生命周期过长,持有状态时间过长。

引用类型

JDK 1.2之后引入四种引用:

  • 强引用Object obj = new Object(),只要强引用存在,垃圾回收器不会回收。
  • 软引用SoftReference类实现,内存不足时回收。
  • 弱引用WeakReference类实现,下次垃圾回收时无论内存是否充足都会回收。
  • 虚引用PhantomReference类实现,无法通过虚引用获取对象实例,回收时会收到系统通知。

判断对象是否存活

  • 引用计数法:为对象添加计数器,引用时+1,失效时-1,为0时回收。
    优点:效率高。
    缺点:无法解决循环引用。
  • 根搜索算法(可达性分析):以“GC Roots”为起点向下搜索,若对象无任何引用链到达GC Roots,则判定为可回收。
    优点:准确解决循环引用。
    缺点:效率相对较低。

可作为GC Roots的对象包括:虚拟机栈引用的对象、方法区静态属性引用的对象、方法区常量引用的对象、Native方法引用的对象等。

方法区的回收

回收废弃的常量、无用的类(需同时满足:所有实例被回收、ClassLoader被回收、Class对象无任何引用)。

垃圾回收算法

算法描述优点缺点
标记-清除标记可回收对象,统一清除基础简单效率低,产生内存碎片
复制算法将内存分为两块,只使用一块,存活对象复制到另一块后整体清理无碎片,实现简单高效内存利用率低(一半)
标记-整理标记后让存活对象向一端移动,再清理边界外内存无碎片,适合老年代效率相对较低
分代收集根据对象存活周期分代,不同代使用不同算法综合优化实现复杂

商业虚拟机中,新生代常用复制算法(Eden:Survivor=8:1:1),老年代常用标记-清除或标记-整理。

内存分配与回收策略

  • 对象优先在Eden区分配

  • 大对象直接进入老年代

  • 长期存活对象进入老年代(年龄计数器)

  • 动态年龄判定:Survivor空间中相同年龄对象总和超过Survivor空间一半,大于等于该年龄的对象直接进入老年代。

  • 空间担保分配:Minor GC前,若老年代连续空间大于新生代所有对象总空间则安全;否则检查HandlePromotionFailure参数,决定是否进行Full GC。

  • Minor GC(新生代GC):频繁,回收速度快。

  • Full GC / Major GC(老年代GC):速度比Minor GC慢10倍以上。