Java虚拟机JVM总结

JVM总共分为四部分:类加载器、运行时数据区、执行引擎、本地库接口

JVM通过类加载器将字节码文件加载到运行时数据区,执行引擎将字节码翻译成底层系统指令,该过程需要调用其它语言的本地库接口,最后由CPU进行处理。

一、类加载器:

类加载过程:加载 --> 检查 --> 准备 -- > 解析 --> 初始化

Java类加载器分为启动类加载器(boostrap classLoader) ---> 扩展类加载器(extend classLoader) --->应用程序类加载器(Application classLoader)

用户也可以自定义类加载器,Spring自定义的类加载器OverringClassLoader破坏了JDK的双亲委托机制。

双亲委托机制:当一个类加载器收到类加载请求时,它首先不会自己先加载,而是把请求委托给它的父类加载器进行加载。这样所有的类加载请求都会到达启动类加载器中。每一层类加载器均是如此,只有父类加载器加载不到时,才会由子类加载器进行加载。好处是同一个类不会由不同的类加载器加载。

二、运行时数据区

运行时数据区分为堆、方法区(永久代)、虚拟机栈、本地方法栈、程序计数器PC

线程公有:堆、方法区(永久代)

线程私有:虚拟机栈、本地方法栈、程序计数器PC

  1. 堆:创建的对象、数组,垃圾收集器的重要区域
  2. 方法区:存放被jvm加载的类信息、常量、静态变量、即时编译器编译后的对象。含运行时常量池
  3. 虚拟机栈:存放栈帧,每一个方法都有一个栈帧组成。栈帧:局部变量表、操作树栈、动态链接、程序出口
  4. 本地方法栈:和虚拟机栈类似,服务的是native方法
  5. 程序计数器PC:记录当前CPU执行的命令位置

永久代内存回收主要针对常量池的回收类型的卸载。JDK8中,永久代被移除,被一个”元数据区“(元空间)的区域所取代。元空间并不在虚拟机中,而是使用本地内存

在分代垃圾收集器中,堆中内存分为年轻代和老年代,默认比例为1:2

年轻代又分为eden区、from survivor区、to survivor区,默认比例为8:1:1。年轻代垃圾回收又称为minorGC,minorGC采用复制算法,过程如下:

  1. 新对象首先出生在eden区,当eden区内存不足时,触发minorGC,将eden区中对象复制到from survivor区
  2. 等eden区+from survivor区再满时,将存活对象复制到to survivor区
  3. 清空eden区+from survivor区
  4. from survivor 和 to survivor 分区互换

每次对象从from survivor区移动到from survivor区时,存活对象年龄都+1,当年龄>=15(在对象头中由4bit表示分代年龄,所以最大也只为15)时,升级为老年代,大对象也会直接进入老年代。

老年代垃圾回收又称为majorGC,采用标记-清除算法 or 标记-整理算法。过程如下:

  1. 标记-清除:首先扫描所有老年代,标记出存活对象,然后回收没有标记的对象。先标记后清楚,会产生内存碎片

  2. 标记-整理:首先扫描所有老年代,标记出存活对象,将存活对象移动到内存的一边,在清楚另一边的对象

新生代收集器

  1. serial垃圾收集器:单线程,复制算法,用于年轻代。
  2. Parallel Scavenge收集器:多线程,复制算法,用于年轻代。主要目的是程序达到一个可控制吞吐量。
  3. ParNew垃圾收集器:多线程,复制算法,用于年轻代。

老年的收集器

  1. Serial Old收集器:单线程,标记-整理算法,用于老年代。
  2. Parallel Old收集器(JDK8默认):多线程,标记-整理算法,用于老年代。
  3. CMS收集器:多线程,标记-清除算法,用于老年代。主要目的是获取最短垃圾回收停顿时间。

CMS工作机制分为四个阶段:

  1. 初始标记:暂停所有工作线程
  2. 并发标记:与用户线程并发执行
  3. 重新标记:暂停所有工作线程
  4. 并发清除:与用户线程并发执行

在分区垃圾收集器中,则将整个堆空间划分为连续的不同小区间Region,每个小区间独立使用,独立回收。好处是可以控制一次回收多少个小区间。

整堆收集器

G1收集器(JDK9以后默认):属于分区收集器,相比CMS两个突出改进:

  1. 基于标记-整理算法,不产生内存碎片
  2. 避免全区域垃圾收集,将根据后台维护的优先级列表和所允许的收集时间,优先回收垃圾最多的区域

三、JVM调优

jps : 查看进程

top : 查看资源占用

kill -3 [pid] : 输出线程相关信息到console

jstack [pid] : 线程的所有堆栈信息

jstat -gc [pid] : 查看gc内容

jinfo : 查看JVM信息

jmap -histo [pid] : 查看JVM堆中对象详细占用情况

jmap -dump:format=b,file=filename.dump [pid] :导出整个JVM 中内存信息

netstat:查看端口情况

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值