美文网首页
Java虚拟机浅浅析

Java虚拟机浅浅析

作者: 瑜小贤 | 来源:发表于2020-04-07 17:31 被阅读0次

Java SE体系架构

虚拟机的发展

  • HotSpot VM
    目前适用范围最广的Java虚拟机
  • JRocket VM
    号称“世界上最快的Java虚拟机”
  • J9 VM
  • Dalvik VM

未来的Java技术

  • 模块化
  • 混合语言
  • 多核并行
  • 丰富语法
  • 64位
  • 更强的垃圾回收

运行时数据区域

  1. 定义
    Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域
  2. 类型
  • 程序计数器 (线程私有)
  • 虚拟机栈(线程私有)
  • 本地方法堆(线程私有)
  • Java堆(线程共享)
  • 方法区(运行时常量池,线程共享)
  • 直接内存

程序计数器

是指向当前线程正在执行的字节码指令地址(行号)(面试点)

为什么需要程序计数器(面试点)

  • Java是多线程的,意味着存在线程切换
  • 确保多线程情况下的程序正常执行

运行时数据区:栈

栈结构
数据结构
  • 入口和出口只有一个
  • 入栈
  • 出栈
特点(面试点)
  • 先进后出(FILO)
为什么JVM要使用栈(面试点)

因为非常符合Java中方法间的相互调用

public class StackFilo {
    public static void main(String[] args)
    {
        A();  //A()->B()->C()
    }
    public static  void A(){
        System.out.println("A开始");
        //此处省略100行代码
        B();//调用B方法
        System.out.println("A结束");
    }
    public static void B(){
        System.out.println("B开始");
        //此处省略100行代码
        C();//调用C方法
        System.out.println("B结束");
    }
    public static void C(){
        System.out.println("C开始");
        //此处省略100行代码
        System.out.println("C结束");
    }
}

//log
A开始 
B开始
C开始
C结束
B结束
A结束
虚拟机栈
  • 定义
    存储当前线程运行方法所需的数据、指令、返回地址
  • 栈帧
    每个方法在执行的同时都会创建一个栈帧
    栈帧还可以划分
  • 局部变量表
  • 操作数栈
  • 动态连接
  • 返回地址
  • 大小设置 (面试点)
  • -Xss JDK 1.8默认1M)
  • 只入栈不出栈,会栈溢出(常见于循环调用、递归调用处理不当)
public class JavaStack {
/*    public static class User{
        public int id = 0;
        public String name = "";
    }*/
    //常量
    final  String Fs ="常在河边走,哪有不湿鞋";
    //静态变量
    static String Ss ="以静制动";
    //次数
    int count =0 ;
    //King老师出差
    public void king(int money){
        //13号技师
        Object tech13 = new Object();
        //调用一次13号服务
        tech13.hashCode();
        int i;
        money = money -100; //花费100
        count++;
        //if(count ==2000) return;
        king(money);
     }
    public static void main(String[] args)throws Throwable {
        JavaStack javaStack = new JavaStack();
        try {
            javaStack.king(10000);
        }catch (Throwable e){
            //输出异常时循环的次数
            System.out.println("栈异常!调用方法(king)的次数():"+javaStack.count);
            throw e;
        }
    }
}
虚拟机栈的执行过程演示.png
本地方法栈
  • 定义
    本地方法栈保存的是native方法的信息
  • 当一个JVM创建的线程调用native方法后,JVM不再为其在虚拟机栈中创建栈帧,JVM只是简单的动态链接并直接调用native方法(例如hashCode()方法)
  • 虚拟机规范无强制规定,每个版本虚拟机自由实现
    HotSpot直接把本地房发展和虚拟机栈合二为一

线程共享区域

方法区
  • 类信息(class)
  • 常量
  • 静态变量
  • 即时编译期编译后的代码

Java堆

  • 对象实例(几乎所有的对象)
  • 数组

堆的大小参数设置

  • -Xmx 堆区内存可被分配的最大上限
  • -Xms 堆区内存出事内存分配的大小

直接内存

不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域

  • 如果使用了NIO,这块区域会被频繁使用,在java堆内可以用directByteBuffer对象直接引用并操作
  • 这块内存不受java堆大小限制,但受本机总内存的限制,可以通过MaxDirectMemorySize来设置(默认与堆内存最大值一样),所以也会出现OOM异常

深入辨析堆和栈

功能

  • 以栈帧的方式存储方法调用的过程,并存储方法调用过程中基本数据类型的变量(int、short、long、byte、float、double、boolean、char)以及对象的引用变量(ref),其内存分配在栈上,变量出了作用域就会自动释放
  • 而堆内存用来存储Java中的对象,无论是成员变量、局部变量,还是类变量,他们指向的对象都存储在堆内存中。

线程独享还是共享

  • 栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即占内存可以理解成线程的私有内存。
  • 堆内存中的对象对所有线程可见。堆内存中的对象可以被所有线程访问。

空间大小

  • 栈的内存要远远小于堆内存,栈的深度是有限制的,可能发生StackOverFlowError的问题

虚拟机中对象

对象的内存布局

对象的访问定位

虚拟机优化技术--逃逸分析

逃逸分析

逃逸分析是目前JVM中比较前沿的优化技术,它不是直接优化手段而是为其他优化手段提供依据的分析技术
逃逸分析的基本行为就是分析对象动态作用域。

栈上分配

99% 对象都在堆上分配
1% 对象可能在创建时经逃逸分析,在栈上分配
如果是栈上分配,就不需要垃圾回收了,会随着线程的结束而消亡

public class StackAlloc {

    public static class User{
        public int id = 0;
        public String name = "";
    }

    
    public static void alloc() {
        User u = new User();  //Object  在堆上分配的() ,有逃逸分析的技术 ,在栈中分配的
        u.id = 5;
        u.name = "King";
    }

    public static void main(String[] args) {
        long b = System.currentTimeMillis(); //开始时间
        for(int i=0;i<100000000;i++) {//一个方法运行1亿次()
            alloc();
        }
        long e = System.currentTimeMillis(); //结束时间
        System.out.println(e-b);//打印运行时间:毫秒
    }

}

牵扯到的JVM参数

-XX:+DoEscapeAnalysis:启用逃逸分析(默认打开)-XX:-DoEscapeAnalysis(关闭)
XX:DoEscapeAnalysis
-XX:+EliminateAllocations:标量替换(默认打开)
-XX:+UseTLAB 本地线程分配缓冲(默认打开)
-XX:+PrintGC(打印垃圾回收过程)

相关文章

  • 两篇文章让你彻底理解Java虚拟机(一)

    Java虚拟机(JVM)浅入深出 Java虚拟机(英语:Java Virtual Machine,缩写为JVM),...

  • JVM 类加载器

    《深入理解Java虚拟机》- 第三版《深入浅出Java虚拟机》- 李国 前言 Java 虚拟机设计团队有意把类加载...

  • JVM 类加载的过程

    《深入理解Java虚拟机》- 第三版《深入浅出Java虚拟机》- 李国 前言 Java 虚拟机中类加载的全过程,即...

  • 浅析Java设计模式【1】——观察者

    前情内容 浅析Java设计模式【1】——观察者 浅析Java设计模式【2】——适配器 浅析Java设计模式【3】—...

  • 浅析Java设计模式【2】——适配器

    前情内容 浅析Java设计模式【1】——观察者 浅析Java设计模式【2】——适配器 浅析Java设计模式【3】—...

  • 浅析Java设计模式【3】——代理

    1. 前情内容 浅析Java设计模式【1】——观察者 浅析Java设计模式【2】——适配器 浅析Java设计模式【...

  • Java-浅析Object类

    Java-浅析Object类 ++2016.7.19++byside @Java-浅析Object类 ======...

  • JAVA虚拟机浅析

    一.程序计数器是一块较小的内存空间,它可以看作是当前线程所执行字节码行数的指示器。在虚拟机的概念模型里,字节码解释...

  • jvm结构&运行机制&多态实现

    浅析Java虚拟机结构与机制 浅谈多态机制的意义及实现 多态:编译时多态(重载)、运行时多态(继承父类、实现接口)...

  • Java虚拟机浅浅析

    Java SE体系架构 虚拟机的发展 HotSpot VM目前适用范围最广的Java虚拟机 JRocket VM号...

网友评论

      本文标题:Java虚拟机浅浅析

      本文链接:https://www.haomeiwen.com/subject/ghgnphtx.html