互联网科技Java基础原理

一篇文章彻底搞懂Java虚拟机

2019-05-21  本文已影响0人  Java_苏先生

概念:

虚拟机:指以软件的方式模拟具有完整硬件系统功能、运行在一个完全隔离环境中的完整计算机系统 ,是物理机的软件实现。常用的虚拟机有VMWare,Visual Box,Java Virtual Machine(Java虚拟机,简称JVM)。

Java虚拟机阵营:Sun HotSpot VM、BEA JRockit VM、IBM J9 VM、Azul VM、Apache Harmony、Google Dalvik VM、Microsoft JVM…

启动流程

基本架构

Java运行时编译源码(.java)成字节码,由jre运行。jre由java虚拟机(jvm)实现。Jvm分析字节码,后解释并执行。

JVM由三个主要的子系统构成:

类加载器子系统

类装载包括了加载,连接(验证、准备、解析(可选)),初始化。其中类加载工作由ClassLoader及其子类负责。

类加载器体系结构

类加载机制(双亲委派)

全盘负责委托机制。全盘负责,当一个ClassLoader加载一个类时,除非显示的使用另一个ClassLoader,该类所依赖和引用的类也由这个ClassLoader载入。委托机制:指先委托父类加载器寻找目标类,在找不到的情况下采用自己的路径中查找并载入目标类

运行时数据区

堆(Java堆)

虚拟机启动时创建,用于存放对象实例,几乎所有的对象(包含常量池)都在堆上分配内存,当对象无法再该空间申请到内存时将抛出OutOfMemoryError异常。同时也是垃圾收集器管理的主要区域。可通过 -Xmx –Xms 参数来分别指定最大堆和最小堆。线程共享。

栈(Java栈)

是java方法执行的内存模型,为虚拟机执行java方法,每个方法在执行的同时都会创建一个栈帧(用于存储局部变量表,操作数栈,动态链接,方法出口等信息)。线程独占。

Jvm对该区域规范了两种异常:

本地方法栈

为虚拟机执行native方法,其他规范与java栈类似。不同类型的虚拟机对该区域可自由实现。线程独占。

PC寄存器(程序计数器)

用来存储待执行指令的地址。分支,循环,跳转,异常处理,线程恢复等功能都需要依赖pc寄存器。线程独占。

若线程执行的是一个java方法,则pc寄存器中保存的是待执行指令的地址。若执行的是一个native方法,则pc寄存器中为空。

元数据区

元数据区取代了永久代,本质和永久代类似,都是对JVM规范中方法区的实现,区别在于元数据区并不在虚拟机中,而是使用本地内存。元数据区在频繁使用,也会发生OutOfMemory异常。

元数据区的动态扩展,默认–XX:MetaspaceSize值为21MB的高水位线。一旦触及则Full GC将被触发并卸载没有用的类(类对应的类加载器不再存活),然后高水位线将会重置。新的高水位线的值取决于GC后释放的元空间。如果释放的空间少,这个高水位线则上升。如果释放空间过多,则高水位线下降。

执行引擎

执行引擎读取运行时数据区的字节码并逐个执行

垃圾收集(GC:Garbage Collection)

GC算法

按照回收策略划分为:标记-清除算法,标记-整理算法,复制算法。

按分区对待可分为:增量收集算法,分代收集算法

按系统线程可分为:串行收集算法,并行收集算法,并发收集算法

GC收集器

垃圾收集算法是内存回收的理论基础,而垃圾收集器就是内存回收的具体实现。

与CMS收集器相比G1收集器有以下特点:

收集器常用组合

JVM性能调优思路

常见异常

  • StackOverflowError:(栈溢出)
  • OutOfMemoryError: Java heap space(堆空间不足)
  • OutOfMemoryError: GC overhead limit exceeded (GC花费的时间超过 98%, 并且GC回收的内存少于 2%)

GC参数

  • 堆栈设置
  • -Xss:每个线程的栈大小
  • -Xms:初始堆大小,默认物理内存的1/64
  • -Xmx:最大堆大小,默认物理内存的1/4
  • -Xmn:新生代大小
  • -XX:NewSize:设置新生代初始大小
  • -XX:NewRatio:默认2表示新生代占年老代的1/2,占整个堆内存的1/3。
  • -XX:SurvivorRatio:默认8表示一个survivor区占用1/8的Eden内存,即1/10的新生代内存。
  • -XX:MaxMetaspaceSize:设置元空间最大允许大小,默认不受限制,JVM Metaspace会进行动态扩展。

并行收集器设置

  • -XX:ParallelGCThreads:设置并行收集器收集时使用的CPU数。并行收集线程数。
  • -XX:MaxGCPauseMillis:设置并行收集最大暂停时间
  • -XX:GCTimeRatio:设置垃圾回收时间占程序运行时间的百分比。公式为1/(1+n)

CMS收集器设置

  • -XX:+UseConcMarkSweepGC:设置CMS并发收集器
  • -XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况。
  • -XX:ParallelGCThreads:设置并发收集器新生代收集方式为并行收集时,使用的CPU数。并行收集线程数。
  • -XX:CMSFullGCsBeforeCompaction:设定进行多少次CMS垃圾回收后,进行一次内存压缩
  • CMSClassUnloadingEnabled:允许对类元数据进行回收
  • -XX:UseCMSInitiatingOccupancyOnly:表示只在到达阀值的时候,才进行CMS回收
  • -XX:+CMSIncrementalMode:设置为增量模式。适用于单CPU情况
  • -XX:ParallelCMSThreads:设定CMS的线程数量
  • -XX:CMSInitiatingOccupancyFraction:设置CMS收集器在老年代空间被使用多少后触发
  • -XX:+UseCMSCompactAtFullCollection:设置CMS收集器在完成垃圾收集后是否要进行一次内存碎片的整理

垃圾回收统计信息

  • -XX:+PrintGC
  • -XX:+PrintGCDetails
  • -XX:+PrintGCTimeStamps
  • -Xloggc:filename

G1收集器设置

  • -XX:+UseG1GC:使用G1收集器
  • -XX:ParallelGCThreads:指定GC工作的线程数量
  • -XX:G1HeapRegionSize:指定分区大小(1MB~32MB,且必须是2的幂),默认将整堆划分为2048个分区
  • -XX:GCTimeRatio:吞吐量大小,0-100的整数(默认9),值为n则系统将花费不超过1/(1+n)的时间用于垃圾收集
  • 目标暂停时间(默认200ms)
  • -XX:G1NewSizePercent:新生代内存初始空间(默认整堆5%)
  • -XX:G1MaxNewSizePercent:新生代内存最大空间
  • 填充容量(默认50%)
  • -XX:MaxTenuringThreshold:最大任期阈值(默认15)
  • -XX:InitiatingHeapOccupancyPercen:老年代占用空间超过整堆比IHOP阈值(默认45%),超过则执行混合收集
  • -XX:G1HeapWastePercent:堆废物百分比(默认5%)
  • -XX:G1MixedGCCountTarget:参数混合周期的最大总次数(默认8)

收集器设置

  • -XX:+UseSerialGC:设置串行收集器
  • -XX:+UseParallelGC:设置并行收集器
  • -XX:+UseParallelOldGC:老年代使用并行回收收集器
  • -XX:+UseParNewGC:在新生代使用并行收集器
  • -XX:+UseParalledlOldGC:设置并行老年代收集器
  • UseConcMarkSweepGC:设置CMS并发收集器
  • -XX:+UseG1GC:设置G1收集器
  • -XX:ParallelGCThreads:设置用于垃圾回收的线程数

性能分析和监控工具

点关注,不迷路;持续更新Java架构相关技术及资讯热文!!!

上一篇 下一篇

猜你喜欢

热点阅读