JVM原理、诊断与优化(1)- 初识JVM

术语

JDK:Java SE Development Kit

JRE:Java SE Runtime Environment 

JVM:Java Virtual Machine

 

1、JDK、JRE和JVM的关系

这是一个老生常谈的问题,简单来说JDK包含了JRE和JVM。

示意图:

看看Oracle官方给出的一个图(链接地址:https://docs.oracle.com/javase/8/docs/):

JDK1.8

与JDK1.7的图有一点点区别。

 (JDK1.7

2、JVM初体验:内存溢出问题的分析与解决

OOM(OutOfMemoryError)异常

在Java虚拟机规范的描述中,除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMemoryError(OOM)异常的可能。

我们在工作中遇到实际的内存溢出异常时,如何能根据异常信息快速判断是哪个区域的内存溢出?什么样的代码可能会导致这些区域内存溢出?以及出现这些异常后该如何处理?

案例一、Java堆溢出

Java堆用于存储对象实例,只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么在对象数量达到最大堆的容量限制后就会产生内存溢出异常。如下代码:

Dog.java

package com.etbird.jvm;

public class Dog {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Dog [name=" + name + "]";
    }
    
}

HeapOOM.java

package com.etbird.jvm;

import java.util.ArrayList;
import java.util.List;

public class HeapOOM {
    public static void main(String[] args) {
        List<Dog> list = new ArrayList<Dog>();
        
        while(true) {
            list.add(new Dog());
        }
    }
}

为了快速模拟这个异常,我们通过设置几个参数:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError

参数说明:

限制Java堆的大小为20MB,不可扩展(即将堆的最小值-Xms参数与最大值-Xmx参数设置为一样,就可以避免堆自动扩展),什么叫做最小值?该java程序一启动时的堆内存大小。什么叫做最大值?java程序运行中最大的堆内存。

在Eclipse中如何配置(Idea中类似的配置,用什么工具都可以)?

右键HeapOOM.java文件 --> Run As --> Run Configurations...,如下图:

 如下图:

 点击“Run”,执行结果如下:

 

 

我们可以看到导出了一个文件:java_pid16568.hprof,这个文件是什么?放在哪里的?

这个文件放在项目的根路径下:

 如何打开这个文件?

可以去下载一个分析工具Memory Analyzer,下载地址:https://www.eclipse.org/mat/downloads.php,如下图:

下载一个独立的文件,如上图中的箭头所示。 

 

3、JVM的概念

JVM是Java Virtual Machine的简称。意为Java虚拟机

什么是虚拟机?

  指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。

有哪些虚拟机?

  VMWare、Visual Box、JVM...

VMWare或者Visual Box都是使用软件模拟物理CPU的指令集。

JVM使用软件模拟Java 字节码的指令集。

4、JVM发展历史

1996年 SUN JDK1.0 Classic VM

  纯解释运行,使用外挂进行JIT。

1997年 JDK1.1发布

  AWT、内部类、JDBC、RMI、反射

1998年 JDK1.2 Solaris Exact VM

  JIT解释器混合

  Accurate Memory Management精确内存管理

  数据类型敏感

  提升的GC性能

  此时,JDK1.2开始 称为Java 2,J2SE J2EE J2ME 的出现,加入Swing、Collections

2000年 JDK1.3 Hotspot 作为默认虚拟机发布

  加入了Java Sound

2002年 JDK 1.4 Classic VM退出历史舞台

  加入了Assert、正则表达式、NIO、IPV6、日志API、加密类库

2004年 JDK1.5 即JDK5、J2SE 5、Java 5

  自动装箱、泛型、动态注解、枚举、可变长参数、遍历循环

2006年 JDK1.6即JDK6

  提供动态语言支持、提供编译API和卫星HTTP服务器API,改进JVM的锁,同步垃圾回收,类加载

2011年 JDK7

  提供GI收集器、加强对非Java语言的调用支持(JSR-292,升级类加载架构

2014年 JDK8

  Lambda 表达式、方法引用、默认方法、新工具、Stream API、Date Time API 、Optional 类、Nashorn, JavaScript 引擎

2017年 JDK9

  模块化

5、大事记

使用最为广泛的JVM为HotSpot

HotSpot为Longview Technologies开发,被SUN收购

2006年Java开源并建立OpenJDK,HotSpot成为Sun JDK和OpenJDK中所带的虚拟机

2008年Oracle收购BEA,得到JRockit VM

2010年Oracle收购Sun,得到Hotspot

Oracle宣布在JDK8时整合JRockit和Hotspot,优势互补,在Hotspot基础上,移植JRockit优秀特性

6、JVM种类

KVM:SUN发布、IOS Android前,广泛用于手机系统

CDC/CLDC HotSpot:手机、电子书、PDA等设备上建立统一的Java编程接口、J2ME的重要组成部分

JRockit:BEA

IBM J9 VM:IBM内部

Apache Harmony:兼容于JDK1.5和JDK1.6的Java程序运行平台;与Oracle关系恶劣退出JCP,Java社区的分裂;OpenJDK出现后,受到挑战2011年退役;没有大规模商用经历;对Android的发展有积极作用

7、Java语言规范

8、JVM规范

 

 关于规范:没有规矩 不成方圆

posted @ 2021-02-05 18:04  外星鸟  阅读(80)  评论(0)    收藏  举报