5.6k 5 分钟

# XML 语言 xml 与 html 都是标准通用标记语言的子集,SGML (SGM) 标准通用标记语言,是一种定义电子文档结构和描述其内容的国际标准语言,具有极好的扩展性。 html 用于显示数据,其中元素是固定的,浏览器解析执行。 xml 用于传输和存储数据,标签可以是用户自定义的, xml 解析器需要自己写。 # 文档声明 xml 文档首先需要使用文档声明来声明文档,且必须出现在文档第一行: <?xml version="1.0" encoding="GB2312"...
3k 3 分钟

# 垃圾收集器 主要是介绍不同收集器得优劣以及使用 单线程与多线程:单线程指的是垃圾收集器只使用一个线程进行收集,而多线程使用多个线程。 串行与并行:串行指的是垃圾收集器与用户程序交替执行,这意味着在执行垃圾收集的时候需要停顿用户程序;并形指的是垃圾收集器和用户程序同时执行。除了 CMS 和 G1 之外,其它垃圾收集器都是以串行的方式执行。 # Serial 收集器 Serial 翻译为串行,即以串行的方式执行。它是单线程的收集器,只会使用一个线程进行垃圾收集工作。在进行垃圾收集时,其他线程都要暂停等待。尽管缺点明显,但是从 JDK1.3.1 开始,Serial...
2.3k 2 分钟

# 对象存活算法 尽量以简短精炼的语言讲解,唔,所见即所得。 # 引用计数算法 给对象添加一个引用计数器,当对象增加一个引用时计数器加 1,引用失效时计数器减 1。引用计数为 0 的对象可被回收。 两个对象出现循环引用的情况下,此时引用计数器永远不为 0,导致无法对它们进行回收。 正因为循环引用的存在,因此 Java 虚拟机不使用引用计数算法。 public class ReferenceCountingGC { public Object instance = null; public static void main(String[] args) {...
2.7k 2 分钟

# 引入 内存模型和内存结构不一样,通过本节从堆栈角度引入 JMM,为后续内容做铺垫。 JMM 在线程栈和堆之间划分内存,如果你系统的学习过 Java,一定听过引用保存在栈中,实例化对象保存在堆中这样的话。从逻辑上说明 JMM: 由线程创建的局部变量对于创建它的线程以外的所有其他线程是不可见的。 即使两个线程正在执行完全相同的代码,两个线程仍将在每个自己的线程堆栈中创建该代码的局部变量。 基本类型的局部变量完全存储在线程堆栈中,对其他线程不可见;但是 new 对象时,都存储在堆上,这个对象的成员变量与对象一起存储在堆上。 # JMM 与硬件内存结构关系 其实该部分在 J.U.C 的...
7.3k 7 分钟

# 前言 关于内存结构的第二篇:包含堆内存,方法区。 # 堆内存 Java 堆是 Java 虚拟机管理的内存中最大的一块,被所有线程共享。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数据都在这里分配内存。 JVM 把堆内存逻辑上划分为三个区域(划分的唯一理由就是优化 GC 性能): 年轻代:新对象和没达到一定年龄的对象都在新生代。 老年代:被长时间使用的对象,老年代的内存空间应该要比年轻代更大。 元空间(JDK1.8 之前叫永久代):像一些方法中的操作临时对象等,JDK1.8 之前是占用 JVM 内存,JDK1.8 之后直接使用物理内存。 主流虚拟机都是可扩展的(通过...
3.7k 3 分钟

# 前言 JVM 内存结构主要分为 5 个: 线程私有:程序计数器,虚拟机栈,本地方法栈。 线程共享:方法区,堆内存。 因为内容较多,所以分两篇讲完。 # 程序计数器 程序计数寄存器(Program Counter Register),Register 的命名源于 CPU 的寄存器,寄存器存储指令相关的线程信息,CPU 只有把数据装载到寄存器才能够运行。 这里,并非是广义上所指的物理寄存器,叫程序计数器(或 PC 计数器或指令计数器)会更加贴切,并且也不容易引起一些不必要的误会。JVM 中的 PC 寄存器是对物理 PC...
5.8k 5 分钟

jvm 启动的时候,并不会一次性加载所有的 class 文件,而是根据需要去动态加载。ClassLoader 的具体作用就是将 class 文件加载到 jvm 虚拟机中去,程序就可以正确运行了。普通的 Java 开发者其实用到的不多,但对于某些框架开发者来说却非常常见。 # 使用 看了很多文章,个人觉得先把如何使用类加载器 -- ClassLoader 弄明白,再来讲解原理效果好得多。 class 字节码文件,需要使用类加载器加载字节码,即在 java 中所有类都会通过加载器加载才能运行。下文提到的类似 Bootstrap ClassLoader , Extension...
3.3k 3 分钟

# 类的生命周期 加载 、 验证 、 准备 和 初始化 这四个阶段发生的顺序是确定的,而 解析 阶段则不一定,它在某些情况下可以在初始化阶段之后开始,这是为了支持 Java 语言的运行时绑定 (也成为动态绑定或晚期绑定)。 这些阶段知识按顺序开始,并不是按顺序结束,这些阶段往往互相交叉混合进行,再一个阶段执行过程中调用或激活另一个阶段。 # 类的加载 首先介绍几个概念: 方法区:JVM 实例内部,类型信息被存储在方法区的内存逻辑区中。类型信息是由类加载时从类文件中提取出来的。方法区又叫做静态区,被所有线程共享,方法区包含所有 class 和 static...
2k 2 分钟

# 访问者 (Visitor) 当想要为对象的组合增加新的能力且封装并不重要时,就可以使用访问者模式。 现在需要知道的就是,被访问的类需要将自身引用传入访问者。讲起来比较空泛,所以先看代码。 # 实现 代码来自菜鸟教程。 定义表示元素的接口: public interface ComputerPart { // 接口定义的行为:元素提供一个方法供访问者进入 // 假设存在 ComputerPartVisitor 接口定义了访问者的 visit 行为 public void accept(ComputerPartVisitor...
4.7k 4 分钟

# JVM 基础 - 字节码增强 字节码增强技术就是一类对现有字节码进行修改或者动态生成全新字节码文件的技术。 # ASM ASM 可以直接生成 .class 字节码文件,也可以在类被加载入 JVM 之前动态修改类行为。ASM 框架是 JDK 内部自带的,最基本的就是通过 ClassWriter 对象编辑类的字节码文件。 public class Main { public static void main(String[] args) { ClassWriter writer = new...