JVM介绍

一、JVM基础

1.JVM(Java虚拟机)

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
在这里插入图片描述

2.Java跨平台性解释

  • java的跨平台,是指java运行时候凌驾于os之上,是在jvm中运行的,跟os没有直接联系。
  • Java属于高级语言中的编译语言,编译语言运行的大致过程为:
    在这里插入图片描述
  • 源文件不能直接被计算机执行,需要相应的编译器,将源代码进行翻译(编译),得到的是汇编语言组成的汇编程序
  • java文件在运行时,会将源文通过javac命令编译为字节码文件,这个文件是跨平台的,java虚拟机(jvm,在java运行环境/jre中)也对应的只接收处理class文件,java虚拟机是一个通用的执行平台(但有不同版本),不同java平台编写文件通过java虚拟机转换的文件最后功能相同,因而实现在任意平台的java程序都可以在其他平台运行。

3.JDK JVM JRE三者的关系

  • JDK(Java Development Kit) 是 Java 语言的软件开发工具包(SDK)。在JDK的安装目录下有一个jre目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib合起来就称为jre。
  • JRE(Java Runtime Environment,Java运行环境),包含JVM标准实现及Java核心类库。JRE是Java运行环境,并不是一个开发环境,所以没有包含任何开发工具(如编译器和调试器)
  • JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
    在这里插入图片描述
    JDK是整个Java的核心,包括了Java运行环境JRE、Java工具和Java基础类库。JRE是运行JAVA程序所必须的环境的集合,包含JVM标准实现及Java核心类库。JVM是整个java实现跨平台的最核心的部分,能够运行以Java语言写的程序。

4.JVM生命周期

main()作为该程序初始线程的起点,任何其他线程均由该线程启动。
当一个程序开始运行时,就是JVM生命的开始,当此程序所有非守护线程结束时JVM退出。

二、类加载机制

1.原理

JVM将class文件字节码文件加载到内存中, 并将这些静态数据转换成方法区中的运行时数据结构,在堆(并不一定在堆中,HotSpot在方法区中)中生成一个代表这个类的java.lang.Class 对象,作为方法区类数据的访问入口。

2.加载过程

  • 从磁盘加载到JAVA虚拟机的过程
  • JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化。
  • 三大阶段
    1.装载阶段:
    类加载器:(继承关系)
    null C/C++终极类加载器
    如果一个类他的类加载器是启动加载器,此时getClassLoader();返回值null C/C++实现
    1)Boostrap ClassLoader 启动类加载器
    路径:jre/lib/.jar ->rt.jar
    2)Ext ClassLoader 拓展类加载器
    路径:jre/lib/ext/
    .jar
  1. App ClassLoader 应用类加载器
    路径:CLASSPATH
    标识文件类型:魔数+次版本号+主版本号
    过程:双亲委派模型
    2.链接阶段:
    1)验证:
    主次版本号
    文件格式验证
    2)准备:
    变量所使用的内存在方法区中进行分配
    count在方法区分配4字节内存,并赋类型默认值为0.
    3)解析:
    将符号引用改为直接引用的过程
    3.初始化阶段:
    给静态变量赋值操作:count=10;
  • 自定义类加载器:
    1.根据路径找到字节码文件 findClass文件
    2.采用双亲委派模型加载 loadClass方法
    3.加载字节码文件生成对应的Class对象

3.系统自带类加载器

  • 启动类加载器。
  • 扩展类加载器。
  • 应用程序类加载器。

4.双亲委派机制

在这里插入图片描述

  • 加载类 ->(parent)委派模型
    找之前是否加载过类,如果加载过,从父类到子类依次尝试加载,将加载产物Class对象返回。如果没有加载过,依次在其父类中查找,直到Boostrap ClassLoader。
    路径找不到加载失败 ClassNotFoundException
  • 双亲委派模型的优点:
    安全性
    避免类的重复加载
    类 类加载器

三、内存模型

1.JVM内存划分

根据JVM规范,JVM 内存共分为虚拟机栈,堆,方法区,程序计数器,本地方法栈五个部分。
在这里插入图片描述

  • 程序计数器(线程私有):
    是当前线程锁执行字节码的行号治时期,每条线程都有一个独立的程序计数器,这类内存也称为“线程私有”的内存。正在执行java方法的话,计数器记录的是虚拟机字节码指令的地址(当前指令的地址)。如果是Natice方法,则为空。
  • java 虚拟机栈(也是线程私有的) 每个方法在执行的时候也会创建一个栈帧,存储了局部变量,操作数,动态链接,方法返回地址。
    每个方法从调用到执行完毕,对应一个栈帧在虚拟机栈中的入栈和出栈。 通常所说的栈,一般是指在虚拟机栈中的局部变量部分。
    局部变量所需内存在编译期间完成分配, 如果线程请求的栈深度大于虚拟机所允许的深度,则StackOverflowError。
    如果虚拟机栈可以动态扩展,扩展到无法申请足够的内存,则OutOfMemoryError。
  • 本地方法栈(线程私有)
    和虚拟机栈类似,主要为虚拟机使用到的Native方法服务。也会抛出StackOverflowError 和OutOfMemoryError。
  • Java堆(线程共享)
    被所有线程共享的一块内存区域,在虚拟机启动的时候创建,用于存放对象实例。
    对可以按照可扩展来实现(通过-Xmx 和-Xms 来控制)
    当队中没有内存可分配给实例,也无法再扩展时,则抛出OutOfMemoryError异常。
  • 方法区(线程共享)
    被所有方法线程共享的一块内存区域。
    用于存储已经被虚拟机加载的类信息,常量,静态变量等。
    这个区域的内存回收目标主要针对常量池的回收和堆类型的卸载。

四、启动参数设置

1.标准参数

功能和输出的参数都是很稳定的 在未来的JVM版本中不会改变 可以使用java -help检索出所有的标准参数

  • server

默认为堆提供了一个更大的空间和并行的垃圾收集器 并且在运行时可以更大程度的优化代码

  • client

客户端虚拟机有较小的默认堆内存 可以缩短JVM启动的时间和占用更少的内存 客户端的JVM只有在32位操作系

2.X参数

非标准化参数 在未来的版本可能会改变 所有的参数都用-X开始 可以使用java -X检索 但是注意没有-Xcomp

  • -XX:+[PARAM], 开启该参数的功能,如-XX:+DisableExplicitGC,开启禁止显式GC
  • -XX:-[PARAM], 关闭该参数的功能,如-XX:-DisableExplicitGC,关闭禁止显示GC
  • -XX:PARAM=VALUE, 设置参数的值,如-XX:SurvivorRatio=80,设置eden/survivor的比值
    关于"-XX"的常见参数,见下面的按功能分类
  • 按功能分类 标记了※的表示常用参数
  • 内存参数
    -Xmx[value] ※ 设置堆内存最大值
  • -Xmx1g 或者
    -Xmx1024m
  • -Xms[value] ※ 设置堆内存最小值。一般与-Xmx设置一样大
  • -Xmn[value] ※ 设置新生代大小
  • -Xss[value] ※ 设置栈空间大小
  • -XX:SurvivorRatio=[value] ※ 新生代Eden和Survivor划分比例
  • -XX:PermSize=[value] ※ 设置永久代初始大小。JDK8中已移除
  • -XX:MaxPermSize=[value] ※ 设置永久代最大值。JDK8中已移除
  • -XX:MetaspaceSize=[value] ※ 设置meta区大小。JDK8增加
  • -XX:MaxMetaspaceSize=[value] ※ 设置永久代最大值。JDK8中已移除
  • -XX:ReservedCodeCacheSize 用于设置Code Cache大小,JIT编译的代码都放在Code Cache中,若Code Cache空间不足则JIT无法继续编译,并且会去优化,比如编译执行改为解释执行,由此,性能会降低
    行为相关参数 Behavioral Options,即影响VM基本行为的参数
    XX:-DisableExplicitGC ※

GC参数

  • -XX:-UseSerialGC 使用串行垃圾回收器回收新生代
  • -XX:+UseParNewGC ※ 使用并行垃圾回收器回收新生代
  • -XX:ParallerGCThreads 当使用-XX:+UseParNewGC时,该参数设定GC的线程数,默认与CPU核数相同
  • -XX:-UseParallelGC 使用Parallel Scavenge垃圾回收器
  • -XX:UseParallelGC = “Parallel Scavenge” + “Serial Old”
  • -XX:-UseParallelOldGC 用并行垃圾回收器进行full gc
  • -XX:UseParallelOldGC = “Parallel Scavenge” + “Parallel Old”
  • -XX:-UseConcMarkSweepGC ※ 使用CMS做为垃圾回收器

注:当前常见的垃圾回收器组合是下面这种:

  • -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
  • -Xloggc:[path] ※ 设置gc日志位置
  • -Xloggc:/opt/logs/mobile/admin.gc.log
  • -XX:+PrintGC ※ 打印GC详情
  • -XX:+PrintGCDetails ※ 打印GC更详细的信息

G1参数
Garbage First Garbage Collection Options

  • -XX:+UseG1GC 使用G1做为垃圾回收器

  • -XX:MaxGCPauseMillis=n Sets a target for the maximum GC pause time. This is a soft goal, and the JVM will make its best effort to achieve
    it.

  • -XX:InitiatingHeapOccupancyPercent=n Percentage of the (entire) heap occupancy to start a concurrent GC cycle. It is used by GCs that
    trigger a concurrent GC cycle based on the occupancy of the entire
    heap, not just one of the generations (e.g., G1). A value of 0
    denotes ‘do constant GC cycles’. The default value is 45.

  • -XX:NewRatio=n old区/new区的比例,默认为2

  • -XX:SurvivorRatio=n eden/survivor的比值,默认为8.

  • -XX:MaxTenuringThreshold=n Maximum value for tenuring threshold. The default value is 15.

  • -XX:ParallelGCThreads=n Sets the number of threads used during parallel phases of the garbage collectors. The default value varies
    with the platform on which the JVM is running.

  • -XX:ConcGCThreads=n Number of threads concurrent garbage collectors will use. The default value varies with the platform on which the JVM is running.

  • -XX:G1ReservePercent=n Sets the amount of heap that is reserved as a false ceiling to reduce the possibility of promotion failure. The
    default value is 10.

  • -XX:G1HeapRegionSize=n
    With G1 the Java heap is subdivided into uniformly sized regions.
    This sets the size of the individual sub-divisions. The default value
    of this parameter is determined ergonomically based upon heap size.
    The minimum value is 1Mb and the maximum value is 32Mb.

3.XX参数

非标准 很长一段时间不会列出来 用于JVM开发的debug和调优

  • -XX:+PrintFlagsInitial 显示JVM所有可设置的参数及它们的值
  • -XX:+PrintFlagsFinal 显示所有可设置的参数及它们的值

可以设置的参数默认是不包括diagnostic或experimental系的。要在-XX:+PrintFlagsFinal的输出里看到这两种参数的信息,分别需要显式指定-XX:+UnlockDiagnosticVMOptions和-XX:+UnlockExperimentalVMOptions。

  • -XX:+ShowMessageBoxOnError 当jvm crash的时候在linux里会启动gdb 去分析和调式,适合在测试环境中使用
  • -XX:+HeapDumpOnOutOfMemoryError ※ OOM的时候dump出内存。
  • -XX:HeapDumpPath dump文件位置。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值