图解Java虚拟机系列(二)节码指令
虚拟机是一个相对于物理机的概念,这两种机器都有代码执行能力,其区别在于物理机的执行引擎是直接建立在 CPU 处理器、指令集、操作系统和硬件层面上的。 而虚拟机的执行引擎则由自己实现,因此可以制定自己的指令集和执行引擎的结构体系,而且还可以执行一些不被硬件直接支持的指令集格式。这就是虚拟机相对于物理机的优势所在。 但是缺点也比较明显,由于多了一层虚拟指令,执行虚拟机指令后还要转化为本地机器码,所以在执行效率上,虚拟机是不如物理机的。 Java 虚拟机的字节码指令由一个字节长度的操作码(Opcode)以及紧随其后的零至多个操作数(Operands)构成。 如果忽略异常处理,那么 Java 虚拟机的解释器通过下面这个伪代码的循环即可有效工作: 1234567do{ 自动计算pc寄存器以及从pc寄存器的位置取出操作码; if(存在操作数){ 取出操作数; } 执行操作码所定义的操作;} while(处理下一次循环); 由于字节码指令集限制了其操作码长度为 1 个字节(0 ~...
图解 Java 虚拟机系列(一)字节码文件结构
我们都知道 .java 文件在执行之前会编译成 .class 文件后再执行。比如下面的代码: 12345678package com.jeanboy.jvm;public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); }} 在 控制台 执行下面命令: $ cd JVMTraning/src/main/java/com.jeanboy.jvm/ $ javac HelloWorld 在 HelloWorld.java 的同级目录下会看到创建了一个 HelloWorld.class 文件。 将 HelloWorld.class 文件用 16 进制编辑器打开,可以看到如下内容: ClassFile 结构每个 class 文件对应一个如下所示的 ClassFile...
深入学习G1垃圾收集器
G1 (Garbage-First) 垃圾收集器在是Java9的默认垃圾收集器。G1 的主要关注点在于达到可控的停顿时间,在这个基础上尽可能提高吞吐量。 如果你的应用使用了较大的堆(如 6GB 及以上)而且还要求有较低的垃圾收集停顿时间(如 0.5 秒),那么 G1 是你绝佳的选择。 从分代上看,G1依然属于分代垃圾回收器,它会区分年代和老年代,依然有eden和survivor区,但从堆的结构上看,它并不要求整个eden区、年轻代或者老年代都连续。 分代收集器将堆分为年轻代、老年代和永久代,每个代空间都是确定的。 而 G1 将整个堆划分为一个个大小相等的小块(每一块称为一个 region),在jvm启动时会设置 region 的数量,取决于堆的大小,每个 region 的大小可在 1MB ~ 32 MB调整,最好不要超过2048个 region 。和分代算法一样,G1 中每个块也会充当 Eden、Survivor、Old 三种角色,但是它们不是固定的,这使得内存使用更加地灵活。 执行垃圾收集时,和 CMS 一样,G1...
深入学习jvm与垃圾回收
一、 Java内存区域常见面试题 介绍下 Java 内存区域(运行时数据区) Java 对象的创建过程(五步,建议能默写出来并且要知道每一步虚拟机做了什么) 对象的访问定位的两种方式(句柄和直接指针两种方式) String 类和常量池 8 种基本类型的包装类和常量池 1. 运行时数据区域 Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。JDK. 1.8 和之前的版本略有不同。 JVM 内存区域主要分为线程私有区域【程序计数器、虚拟机栈、本地方法区】、线程共享区域【JAVA 堆、方法区】、直接内存。线程私有数据区域生命周期与线程相同, 依赖用户线程的 启动/结束 而 创建/销毁 (在 Hotspot VM 内, 每个线程都与操作系统的本地线程直接映射, 因此这部分内存区域的存/否跟随本地线程的生/死对应)。 1.1程序计数器(线程私有)一块较小的内存空间, 是当前线程所执行的字节码的行号指示器,每条线程都要有一个独立的程序计数器,这类内存也称为“线程私有”的内存。正在执行 java...