JVM虚拟机基础知识

Posted gaoyuanzhi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM虚拟机基础知识相关的知识,希望对你有一定的参考价值。

1. Java的发展

Java之父:詹姆斯·高斯林

2. Java的技术体系

  1. Java 程序设计语言
  2. JVM
  3. class文件格式
  4. 编译器
  5. Java API
  6. 第三方Java类库

Java SE(Java Standard edition)
Java ME(Micro Edition)
Java EE(Java Enterprise Edition)

3. JVM的安装

                                                                                   

4. JDK、JRE、JVM的关系

JDK(Java Development Kit)
JRE(Java Runtime Environment)
JVM(Java Virtual Machine)

官方结构图:https://docs.oracle.com/javase/8/docs/

5.Java8的新特性

  1. 引入lambda表式式
  2. Nashorn javascript引擎,使用Metaspace 代替PermGen space
  3. Date API
  4. 更好的类型判断

6.Java 虚拟机产品

  1. Sun Classic VM :第一款商用虚拟机,只能使用纯解释器的方式来执行Java代码。已被淘汰
  2. Exact VM (Exact Memory Management) : 编译器和解释器混合工作以及两级及时编译器,只在solaris平台发布
  3. HotSpot VM: Longview Technologies-->SUN-->Oracle
  4. KVM(Kilobyte): 简单、轻量、高度可移植,在手机平台运行。运行速度慢
  5. JRockit: BEA--> Oracle,专注服务端应用,优势:垃圾收集器+MissionControl服务套件
  6. J9( IBM Technology for Java Virtual Machine IT4j ): IBM公司开发,用于IBM的产品
  7. dalvik: Google公司设计,android平台核心组成部分之一
  8. Mircosoft JVM:
  9. Azul VM: 高性能,HotSpot 基础上改进
  10. Liquid VM: 高性能,BEA公司开发,本身相当于一个操作系统
  11. TaobaoVM: 根据OpenJDK深度定制

    7.JVM内存管理

    运行时数据区

    1. 线程共享区

    1.1. 方法区

  12. 保存类的元数据
  13. 元数据包括类型信息、常量池、域信息、方法信息
  14. 在HotSpot虚拟机中,方法区也被成为永久区
  15. 虽然叫做永久区,但是在永久区的对象也可以被GC回收

1.1.1 运行时常量池

  1. 方法区的一部分
  2. 用于存放编译器生成的各种字面量和符号引用

    1.2. Java堆

  3. 存放对象实例
  4. 垃圾收集器管理的主要区域
  5. 新生代、老年代
  6. OutofMemoryError:内存溢出

    2. 线程独占区

    2.1. Java虚拟机栈

  7. 描述的是Java方法执行的动态内存模型
  8. Java虚拟机栈主要被用来存放基本类型的变量,如:int、short、long、byte、float、double、boolea、char、对象引用
  9. StackoverflowError: 栈内存溢出,可以使用-XSS指定虚拟机栈的大小,栈的大小决定了函数调用的最大可达深度
  10. 虚拟机栈为虚拟机执行Java方法

    2.2. 本地方法栈(Native Method Stacks)

  11. 本地方法栈用来执行Native方法

    2.3. 程序计数器(Program Counter Register)

  12. 每一个线程都有一个独立的程序计数器,用来记录下一条需要执行的计算机指令
  13. 程序计数器是线程独有的一块内存空间。这块内存是线程私有,生命周期与线程保持一致
  14. 如果当前线程正在执行一个Java方法,则程序计数器记录正在执行的Java字节码地址,如果当前线程正在执行一个本地方法,则程序计数器为空
  15. 唯一一个在Java虚拟机中内有规定任何OutofMemoryError情况的区域

8. 对象

8.1 对象的创建

1.给对象分配内存的方式

  1. 指针碰撞
  2. 空闲列表

    2. 线程的安全性问题

  3. 线程同步(需要加锁,效率低)
  4. 本地线程分配缓冲

    3. 初始化对象

    4. 执行构造方法

8.2对象的结构:

1.自身运行时数据(Mark Word)

  • 哈希值
  • GC分代年龄
  • 锁状态标识
  • 线程持有的锁
  • 偏向线程ID
  • 偏向时间戳
    占用的空间:32位机器:32bit;64位机器:64bit
  1. 类型指针

    2.InstanceData

    3.Padding

    8.3 对象的访问定位

    1.使用句柄
    2.直接指针

9.垃圾回收

9.1 如何判断对象为垃圾对象?

  1. 引用计数法
    在对象中添加一个引用计数器,当有地方引用这个对象时计数器的值就+1,当引用失效时,计数器的值就-1
    弊端:当对象循环引用时不能识别是否为垃圾对象
    *基本没有JVM在使用
  2. 可达性分析法
    作为GCroot的对象
    • 虚拟机栈
    • 方法区的类属性所引用的对象
    • 方法区中常量所引用的对象
    • 本地方法栈中引用的对象

JDK8使用的垃圾回收器: parallel

9.2 回收算法

  1. 标记-清除算法
    通过可达性分析法标记-->清楚
    缺点:效率较低、空间问题(出现很多不连续的内存空间)
  2. 复制算法
    把使用中的内存复制一份重新按顺序排列
    缺点:内存只能用一半,不适用于老年代
  3. 标记-整理算法
    让所有存活的对象都向一端移动,然后清理掉边界以外的内存
  4. 分代收集算法

  • 新生代
    • Eden 伊甸园
    • Survivor 存活区
    • Tenured Gen
  • 老年代

9.3 垃圾收集器

1. serial收集器

  1. 历史最悠久
  2. 使用复制算法
  3. 单线程,垃圾收集时必须暂停其他所有的工作线程,直到收集结束
  4. 虚拟机运行在Client模式下的新生代收集器
  5. 用于桌面应用

2. ParNew收集器

  1. 多线程收集
  2. 虚拟机运行在Server模式下首选的新生代收集器

3. parallel Scavenge收集器

  1. 适用复制算法(新生代内存)
  2. 多线程收集器
  3. 达到可控制的吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)
  4. -XX:MaxGCPauseMillis 垃圾收集器停顿时间
  5. -XX:GCTimeRatio 吞吐量大小 (0-100)

4. cms(Concurrent Mark Sweep)收集器

  1. 运作步骤
    标记清除--并发标记--重新标记--并发清除
  2. 优点
    • 并发收集
    • 低停顿
  3. 缺点
    • 占用大量的CPU资源
    • 无法处理浮动垃圾
    • 出现Concurrent Mode Failure
    • 基于标记清除算法,会产生大料的空间碎片

      5. G1(Garbage-First)收集器

面向服务端应用的垃圾收集器
优势:

  1. 并行与并发, 使用多个CPU来缩短Stop-The-Word停顿时间
  2. 分代收集
  3. 空间整合:整体上看基于标记-整理算法,局部上看基于复制算法
  4. 可预测停顿

运作步骤:

  1. 初始标记
  2. 并发标记
  3. 最终标记
  4. 筛选回收 Remembered Set

10 . 内存分配

10.1 优先分配到Eden区

10.2 大对象直接进入老年代

10.3长期存活的对象进入老年代

10.4 空间分配担保

10.5 动态对象的年龄判断

11. JVM工具

https://docs.oracle.com/javase/8/docs/technotes/tools/index.html#monitor

11.1 jps (Java Process Status)

[email protected]:~$ jps
13154 Bootstrap
12191 Jps

参数:

# -l :虚拟机执行主类名称或者jar包的名称
[email protected]:~$ jps  -l
13154 org.apache.catalina.startup.Bootstrap
12462 sun.tools.jps.Jps
# -m :主类接收的参数
[email protected]:~$ jps  -m
13154 Bootstrap start
12552 Jps -m
# -v :JVM接收的参数
[email protected]:~$ jps  -v
13154 Bootstrap -Djava.util.logging.config.file=/home/jenkins/tomcat/jenkins/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -Dcatalina.base=/home/jenkins/tomcat/jenkins -Dcatalina.home=/home/jenkins/tomcat/jenkins -Djava.io.tmpdir=/home/jenkins/tomcat/jenkins/temp
12675 Jps -Denv.class.path=.:/home/ubuntu/software/jdk/jdk1.8.0_151/lib:/home/ubuntu/software/jdk/jdk1.8.0_151/jre/lib -Dapplication.home=/home/ubuntu/software/jdk/jdk1.8.0_151 -Xms8m

11.2 jstat

虚拟机统计信息监控:类装载、内存、垃圾收集、JIT编译等运行数据

11.3 jinfo

实时查看和调整虚拟机各项参数

11.4 jmap

生产堆转储快照

$ jmap -dump:format=b,file=jenkins.bin 13154
Dumping heap to /home/jenkins/jenkins.bin ...
Heap dump file created

-XX:+HeapDumpOnOutofMemoryError : 虚拟机在OOM异常出现后自动生成dump文件

# 显示堆中对象通信信息
$ jmap -histo 13154 | less

11.5 jhat

功能:分析jamp生成的堆转储快照
一般不会在生产服务器上进行分析,非常耗CPU和内存,不常用

[email protected]:~$ jhat jenkins.bin 
Reading from jenkins.bin...
Dump file created Thu Feb 14 11:43:45 CST 2019
Snapshot read, resolving...
Resolving 12022774 objects...
Chasing references, expect 2404 
dots
Eliminating duplicate references
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

浏览器访问http://ip:7000 查看分析结果

11.7 jstack

功能: 生成虚拟机当前时刻的线程快照,用来定位线程出现长时间停顿的原因,如线程见死锁、死循环、请求外部资源导致的长时间等待等

jstack -l 13154

11.8 jconsole

  1. 内存监控
  2. 线程监控
  3. 死锁

    11.9 jvisualvm

12. 性能调优

调优需要的技能:

  1. 知识
  2. 工具
  3. 数据
  4. 经验


















以上是关于JVM虚拟机基础知识的主要内容,如果未能解决你的问题,请参考以下文章

详解Jvm内存结构

详解Jvm内存结构

Java基础—Java虚拟机JVM

JVM基础知识

JAVA基础知识|java虚拟机(JVM)

# 技术栈知识点巩固——Jvm