概述 执行引擎是 Java 虚拟机最核心的组成部分之一。“虚拟机”是一个相对于“物理机”的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、硬件、指令集和操作系统层面上的,而虚拟机的执行引擎是有自己实现的,因此可以自行制定指令集与引擎的结构体系,并且能够执行那些不被硬件直接支持的指令集格式。 Java 虚拟机规范中制定了虚拟机字节码执行引擎的概念模型,这个概念...
类加载器
概述 上一篇文章学习了类加载的过程,并且只是简单的说到了使用类加载器加载类,而这一篇文件则详细的介绍一下类加载过程。 虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取此类的二进制字节流”这个动作放到 Java 虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类,这个动作的代码模块称为 “类加载器”。类加载器在类层次划分,OSGi、热部署、代码加密等领域大放异彩,称为 ...
JVM 类加载机制
概述 虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这就是虚拟机的类加载机制。 Java 语言里面,类的加载、连接和初始化过程都是在程序运行期间完成的,这种策略虽然会令类加载时稍微增加一些性能开销,但是会为 Java 应用程序提供了高度的灵活性,Java 里天生可以动态扩展的语言特性(我理解就是多态...
JVM 故障排查常用命令
概述 前面几篇文章介绍了 JVM 的内存分配机制和垃圾回收机制,这篇文章主要介绍一些在当 JVM 发生故障时定位分析问题所使用到的一些工具,使用这些工具可以用来打印运行日志、异常堆栈、GC 日志 或者导出线程快照(threaddump/javacore 文件)、堆转储快照(heapdump/hprof 文件)等。常用的工具如下: 名称 主要作用 ...
Java 内存分配策略
概述 学习完了 Java 内存回收策略,我们在调过头来学习一下内存分配策略。内存分配策略大方向就是向怼上进行分配(但可能经过 JIT 编译后被拆散为标量类型并间接地栈上分配),对象主要分配在新生代的 Eden 区,如果启动了本地线程分配缓冲,将按线程优先分配在 TLAB 上分配。少数情况下也可能会直接分配在老年代中,分配到规则并不是百分之百固定的,其细节取决于当前使用的哪一块垃圾收集器组合...
Java Reference & ReferenceQueue
Reference 在 JDK 1.2 之前,Java 中的引用的定义很传统:如果 reference 类型的数据中存储的数值代表的是另一块内存的起始地址,就称这块内存代表着一个引用。这种定义很纯粹,但是太多狭隘,一个对象在这种定义下只有被引用活着没有被引用两种状态。在 JDK 1.2 之后,Java 对引用的概念进行了扩充,将引用分为强引用(Strong Reference)、软引用(S...
JVM 垃圾回收机制知识点整理
概述 Java 与 C++ 之间有一堵由动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人却想出来。说起 GC,大部分人都把这项技术当做 Java 语言的半生产物。事实上,GC 的历史比 Java 久远,1960 年诞生于 MIT 的 Lisp 是第一门真正使用内存动态分配和垃圾收集技术的语言。当 Lisp 还在胚胎时期时,人们就在思考 GC 需要完成的三件事: ...
ConcurrentHashMap 简述(JDK 1.8)
概述 之前了解的相关 HashMap 都是线程不安全的,今天来看下线程安全的相关 Map,其中较为熟悉的 Hashtable 和 ConcurrentHashMap 两个。其中 Hashtable 是在 HashMap 的基础上将所有的方法是 synchronized 关键字修饰,锁的作用范围是当前对象,每次只允许一个线程访问当前 map,性能极其差,而 ConcurrentHashMap...
LinkedHashMap 源码解读(JDK 1.8)
概述 不久前阅读了 HashMap 的源码,今天来看下 LinkedHashMap 的源码,LinkedHashMap 继承自 HashMap,然后在类中新增了 head、tail、accessOrder 三个字段,其中会将插入、删除的数据与 head、tail 这两个字段进行关联,也就是说 LinkedHashMap 通过 head、tail 来保留了插入时的顺序。在查询到某个节点时,如...
TreeMap 源码解读(JDK 1.8)
概述 TreeMap 从名字中可以看出应该是跟树有关,没错,TreeMap 便是直接使用红黑树实现的,而 HashMap 则是当链表数组和某个链表同时达到一定长度时才会将链表转为红黑树。同时 TreeMap 还是有序的,这就要求 Key 必须是可以进行比较的!即实现 Comparable 接口,否则在插入或者查询时会抛出类型转换异常,接下来看源码。 源码 public class Tr...