JVM学习笔记9:垃圾回收

引用计数法与可达性分析

  • 引用计数没啥可说的,就是对堆中的对象记录有多少对象来持有它。在我的理解中最多的应该还是变量来引用,还有如果是与native的代码交互,可能还有指针来持有。

  • 可达性是用来解决互相引用问题的,这个算法的实质在于将一系列 GC Roots 作为初始的存活对象合集(live set),然后从该合集出发,探索所有能够被该集合引用到的对象,并将其加入到该集合中,这个过程我们也称之为标记(mark)。最终,未被探索到的对象便是死亡的,是可以回收的。

  • 那么什么是 GC Roots 呢?我们可以暂时理解为由堆外指向堆内的引用,一般而言,GC Roots 包括(但不限于)如下几种:

    • Java 方法栈桢中的局部变量;
    • 已加载类的静态变量;
    • JNI handles;
    • 已启动且未停止的 Java 线程。

JVM学习笔记8:Java对象的内存布局

对象创建方式

  • 6种方法创建对象,但是不同的方法对于实例字段的初始化是不同的:
    • 直接复制已有的数据到实例化字段:Object.clone 方法和反序列化
    • 没有初始化实例字段:Unsafe.allocateInstance
    • 通过调用构造器来初始化实例字段: new 语句和反射机制

JVM学习笔记7:invokedynamic

问题的产生

  • 在java中实现动态语言的能力
  • Java 7 引入了一条新的指令 invokedynamic。该指令的调用机制抽象出调用点这一个概念,并允许应用程序将调用点链接至任意符合条件的方法上
    作为 invokedynamic 的准备工作,Java 7 引入了更加底层、更加灵活的方法抽象 :方法句柄(MethodHandle)。

JVM学习笔记6:反射

反射的实现

  • 横向比对C#,几乎是是一样的

核心是invoke函数

1
2
3
4
5
6
7
8
9
10
11
public final class Method extends Executable {
...
public Object invoke(Object obj, Object... args) throws ... {
... // 权限检查
MethodAccessor ma = methodAccessor;
if (ma == null) {
ma = acquireMethodAccessor();
}
return ma.invoke(obj, args);
}
}

JVM学习笔记5:异常处理

异常的分类

  • 显式:主体是应用程序,它指的是在程序中使用“throw”关键字,手动将异常实例抛出。
  • 隐式:主体则是 Java 虚拟机,它指的是 Java 虚拟机在执行过程中,碰到无法继续执行的异常状态,自动抛出异常。举例来说,Java 虚拟机在执行读取数组操作时,发现输入的索引值是负数,故而抛出数组索引越界异常(ArrayIndexOutOfBoundsException)。

JVM学习笔记4:方法调用

重载与重写

  • 重载的方法在编译阶段完成识别,调用是根据参数声明类型选择重载方法。选择分三个阶段:

    • 在不考虑对基本类型自动装拆箱(auto-boxing,auto-unboxing),以及可变长参数的情况下选取重载方法;
    • 如果在第 1 个阶段中没有找到适配的方法,那么在允许自动装拆箱,但不允许可变长参数的情况下选取重载方法;
    • 如果在第 2 个阶段中没有找到适配的方法,那么在允许自动装拆箱以及可变长参数的情况下选取重载方法。
  • 如果 Java 编译器在同一个阶段中找到了多个适配的方法,那么它会在其中选择一个最为贴切的,而决定贴切程度的一个关键就是形式参数类型的继承关系。

  • 下面代码中第一次调用会是函数2,因为null可以匹配object和string,但是因为string是Object的子类,所以编译器认为string合适。

JVM学习笔记3:类加载

知识点

  • 基本步骤:经过加载、链接以及初始化三大步骤。其中,链接过程中同样需要验证;而内存中的类没有经过初始化,同样不能使用。
  • 引用类型与CLR基本一致,泛型会被编译为特定类型的代码。类和接口是字节码。数组类是由 Java 虚拟机直接生成的,这个似乎没有CLR中对标的东西。
  • 加载用的字节流可以来自java编译后的class,也可以是网络比如网页中内嵌的小程序 Java applet。字节流我理解就是IL,而且从结果看也确实就是这个东西。

JVM学习笔记2:类型

Boolean

  • Java中的Boolean类型在JVM中映射为int类型。“true”被映射为整数 1,而“false”被映射为整数 0。因此,将原本声明为 boolean 类型的局部变量,赋值为除了 0、1 之外的整数值,在 Java 虚拟机看来是“合法”的。

  • 对于存储 boolean 数组的字节码,Java 虚拟机需保证实际存入的值是整数 1 或者 0。

  • 对于下面的代码来说,第一个if是true,第二个是false。因为第一个是在true是1的情况下,等于问的是“吃过几碗饭”,而第二个if是问“吃了一碗饭吗”。

JVM学习笔记1:概述

JVM解决什么问题

  • JVM在我的理解与CLR是一回事,本身还是为了解决java代码无法直接编译为机器码。
  • 对标C#,类型的动态推导等功能是在运行时做的,因此无法做到AOT。就需要虚拟机来做这个事情了。
  • 如虚函数实现多态这样的情况,JVM中可以简单的获得当前应该调用哪个实现函数,从而优化代码的执行。
  • 最后,使用虚拟机可以做到代码不考虑具体在哪个平台运行的问题,实现跨平台使用。

How I build games with Entitas 摘要

  • 这篇文章并不会讲解entitas的功能,作者在文章中主要谈了谈他如何利用entitas开发清晰、稳定和灵活的代码结构。这篇文章可以说是对于ECS的一种实践的总结,同时也是对于Entitas的使用总结。
  • 文章会介绍如下的话题:
    • 定义:数据、逻辑和视图层
    • 维护它们彼此的独立
    • 通过接口进行抽象
    • IOC
    • 视图层抽象(视图和视图控制器)
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×