kvm源码解析
此KVM不是目前特别火的Kernel-based Virtual Machine(一个开源的系统虚拟化模块).而是一个JAVA 的虚拟机.是J2ME cldc 的一个实现.其源码的难度比hotspot简单多了.因此,想通过研读KVM,以加深对hotspot的理解
一个努力的码农
这个作者很懒,什么都没留下…
展开
-
kvm线程-006-线程状态-THREAD_ACTIVE
本文介绍线程状态THREAD_ACTIVE的使用.设置线程状态THREAD_ACTIVE的地方有:InitializeThreading,这点在kvm启动流程-006 中有详细介绍.resumeThread,其代码如下: void resumeThread(THREAD thisThread) { // 如果状态不是THREAD_SUSPENDED,则抛出异常...原创 2019-07-25 14:47:39 · 5310 阅读 · 0 评论 -
kvm线程-005-线程状态-THREAD_JUST_BORN
在kvm内部定义了线程状态,如下: enum { THREAD_JUST_BORN = 1, /* 还没有启动*/ THREAD_ACTIVE = 2, /* 当前正在运行,或者在等待运行的队列中*/ THREAD_SUSPENDED = 4, /* 等待monitor或者alarm */ THR...原创 2019-07-25 11:00:45 · 5383 阅读 · 0 评论 -
kvm 本地方法实现
本文介绍kvm中本地方法的实现.在j2me_cldc/kvm/VmCommon/h/native.h中有如下定义:typedef void NativeFunctionType(void);typedef NativeFunctionType *NativeFunctionPtr; // 函数指针typedef struct { const char *const name; /...原创 2019-07-24 18:44:52 · 5323 阅读 · 0 评论 -
kvm线程-004-线程切换
本文介绍kvm中线程切换的实现.通过kvm线程-001的介绍.可以得到如下事实:对于通过new Thread() 创建的线程,其分配的时间片为:priority * 1000.其代码如下: void Java_java_lang_Thread_setPriority0(void){ int priority = popStack(); THREAD VMthrea...原创 2019-07-23 15:32:48 · 5291 阅读 · 1 评论 -
kvm线程-003
本文介绍kvm中关于线程操作中的下列函数:registerAlarmcheckTimerQueueremovePendingAlarm这三个函数,涉及到了一个队列–TimerQueue.其定义如下:THREAD TimerQueue;typedef struct threadQueue* THREAD;而threadQueue(说是queue,其数据结构上是用链表...原创 2019-07-22 18:27:52 · 5272 阅读 · 0 评论 -
kvm线程-002
kvm在内部定义了很多方法来操作线程,如下:/* 线程的构造 */void InitializeThreading(INSTANCE_CLASS, ARRAY);THREAD getVMthread(JAVATHREAD_HANDLE);/* 线程操作 */void initThreadBehavior(THREAD, METHOD, OBJECT);void...原创 2019-07-22 16:24:16 · 5384 阅读 · 0 评论 -
kvm线程-001
KVM具有独立于机器的、可移植的线程模型,可以独立于Java语言运行.其变化如下:1.0之前使用了一个简单的循环调度模型,其中系统中的所有活动线程都存储在循环列表中.列表中的线程根据每个任务的Java级优先级,一个接一个地执行。在实现级别,线程优先级只是一个整数,它告诉解释器在下一个线程切换发生之前,线程可以执行多少原语。在每个字节码执行之后,线程的“Timeslice”计数器将递减。当时...原创 2019-07-22 14:56:17 · 5380 阅读 · 0 评论 -
kvm垃圾收集-008-更新对象引用
本文介绍在压缩内存后更新对象引用的代码,这部分的代码如下:// 修改指针updateRootObjects(¤tTable);updateHeapObjects(¤tTable, freeStart);其中updateRootObjects的代码如下:static voidupdateRootObjects(breakTableStruct *...原创 2019-07-22 10:50:27 · 5169 阅读 · 0 评论 -
kvm垃圾收集-压缩算法实现,独家
本文介绍kvm中垃圾收集算法中的压缩部分.这里涉及到BreakTable 这么一个数据结构,BreakTable的每个表项对应于在garbage collector进行compating的过程中每个被移动了的object,每个表项含有两个字段,其中address表示该项对应的object被移动前在内存中的起始地址,offset表示该object在compacting过程中相对于原地址移动的偏移量...原创 2019-07-22 10:15:29 · 5307 阅读 · 0 评论 -
kvm垃圾收集-006
本文介绍kvm中垃圾收集中的sweep.sweep的意思是: 将垃圾对象清除(其实垃圾区域的对象还是存在的,但是由于没有对象引用,同时之后在分配对象时,会在这些区域分配,分配时会进行清零操作.因此,也就表现为实际清除了一样)。此处的代码如下:static CHUNKsweepTheHeap(long *maximumFreeSizeP){ CHUNK firstFreeChunk =...原创 2019-07-19 11:49:41 · 5321 阅读 · 0 评论 -
kvm垃圾收集-005
本文介绍garbageCollectForReal中的第3步–markWeakPointerLists,第4步–markWeakReferences.markWeakPointerLists其代码如下:static voidmarkWeakPointerLists(){ WEAKPOINTERLIST list; /* 1. 保存本地方法指针 */ cell* ...原创 2019-07-19 11:34:46 · 5371 阅读 · 0 评论 -
kvm垃圾收集-004
本文介绍garbageCollectForReal方法中的第二步–markNonRootObjects.该方法的功能是扫描堆中存活对象,将其所引用的对象标记为存活.该方法使用了尾递归的方式扫描整个堆.同时为了防止递归次数过多,设置了阀值.最多递归次数为MAX_GC_DEPTH(4).这样,不管对象多少,则一定会处理完毕的.markNonRootObjects的代码如下:static voi...原创 2019-07-18 20:38:33 · 5335 阅读 · 0 评论 -
kvm垃圾收集-003
本文介绍在kvm中垃圾收集的实际实现,其方法名为garbageCollectForReal.其代码如下:voidgarbageCollectForReal(int realSize){ CHUNK firstFreeChunk; long maximumFreeSize; /* The actual high-level GC algorithm is here *...原创 2019-07-18 17:44:11 · 5391 阅读 · 0 评论 -
kvm垃圾收集-002
本文我们来介绍kvm中的垃圾收集器的实现.其算法为mark-and-sweep(含有压缩功能).其方法为garbageCollect.代码如下:voidgarbageCollect(int moreMemory){#if INCLUDEDEBUGCODE int beforeCollection = 0; int afterCollection = 0;#endif ...原创 2019-07-18 11:41:37 · 5525 阅读 · 0 评论 -
kvm free chunk list
在kvm内部中在分配内饰时使用了free chunk list.其定义如下:struct chunkStruct { long size; /* 当前chunk的大小,不包含该字段 */ CHUNK next; /* 指向下一个chunk */};如图所示:这里需要注意的是:size使用与常规对象头相同的格式存储,但是只使用最高的24位(见...原创 2019-07-16 18:07:25 · 5499 阅读 · 0 评论 -
kvm对象头
在之前的文章中,简要说了一下kvm中的对象头,kvm中的对象头和jvm中的不完全相同.本文进行详细介绍.在我们的VM中,内存中的每个堆分配结构前面都有一个对象头,它提供关于对象类型和大小的详细信息。头的长度是一个字(32位)。如图:这里有一定注意的是,在kvm中是没有对象句柄。因此,与许多其他JVM实现(openjdk)不同,所有内存引用都是直接的,而不是间接的。对象头出于管理目的,其是...原创 2019-07-15 16:45:55 · 5459 阅读 · 0 评论 -
kvm垃圾收集-001
kvm中的垃圾收集算法是基于Cheney的elegant copying collector而来.尽管该收集器有很多好处(特别是,它使用迭代而不是递归算法来收集对象).但它有复制收集器的一般问题,因为它需要比程序实际使用的内存空间多一倍的内存空间。当将KVM移植到内存非常有限的设备(如PalmPilot)上运行时,这一要求是有问题的。为了使kvm更适合小型设备,针对kvm 1.0实现了一种新的垃...原创 2019-07-12 19:20:25 · 5587 阅读 · 0 评论 -
kvm终止流程
本文介绍KVM的终止流程.其是在StartJVM方法中调用的.代码如下:int StartJVM(int argc, char* argv[]){ volatile int returnValue = 0; /* Ensure that we have a class to run 必须提供要运行的类名 */ if (argc <= 0 || argv[0] =...原创 2019-07-12 11:39:00 · 3979 阅读 · 1 评论 -
kvm-inlineCache
本文来详细介绍kvm中的inlineCache.其定义如下:struct icacheStruct { cell* contents; /* 指向实际要执行方法 */ BYTE* codeLoc; /* 指向引用内联缓存项的代码位置*/ short origParam; /* 原始字节码的参数,其值= codeLoc+1 */ BYTE orig...原创 2019-07-11 12:12:12 · 4804 阅读 · 0 评论 -
kvm解释器-004
本文介绍主类main方法执行的过程.其字节码如下:另外,此处主类反编译后的结果如下:# 参数 hejiarui$ javap -v -l -p -c -s -constants KVMTest.class Classfile KVMTest.class Last modified Jul 8, 2019; size 415 bytes MD5 checksum be7ceda6878...原创 2019-07-10 17:00:33 · 4768 阅读 · 0 评论 -
kvm解释器-003
本文继续介绍kvm中解释执行的步骤.接上文,目前栈中的情况如图所示:初始化Thread此处初始化的步骤和上文中介绍的一样,也是调用runClinit方法.首先设置初始化线程为CurrentThread,然后由于其父类Object此时的状态为CLASS_READY,因此就不需要初始化父类了.此处的代码如下:if ((thisClass->clazz.accessFlags & ...原创 2019-07-10 16:58:40 · 4824 阅读 · 0 评论 -
kvm解释器-002
在JAVA虚拟机规范(JAVA SE 7 )中,针对初始化的过程有如下的定义:每个类或接口C,都有一个唯一的初始化锁LC。如何实现从C到LC的映射可由Java虚拟机实现自行决定。例如,LC可以是C的Class对象,或者是与Class对象相关的管程(Monitor)。初始化C的过程如下:同步C的初始化锁LC。这个操作会导致当前线程一直等待直到可以获得LC锁如果C的Class对象显示当前C的初...原创 2019-07-09 16:04:09 · 4853 阅读 · 0 评论 -
kvm解释器-001
从本文开始接受kvm中解释器是如何执行的流程.以一个例子来进行说明,如下:public class KVMTest{ public static void main(String[] args){ System.out.println("success"); } }javap后,其结果如下:# 命令行为: javap -v -l -p -c ...原创 2019-07-09 16:01:38 · 5023 阅读 · 2 评论 -
kvm启动流程-006
本文介绍kvm启动过程中比较复杂的步骤,初始化多线程系统与初始化系统类初始化多线程系统此处的代码如下:void InitializeThreading(INSTANCE_CLASS mainClass, ARRAY argumentsArg){ START_TEMPORARY_ROOTS /* * ARRAY arguments = ( arg...原创 2019-07-09 15:54:20 · 5057 阅读 · 0 评论 -
kvm启动流程-005
写在前面这是本人的第100篇博文,随着不断的看源码,不知不觉已有这么多…前言kvm在启动时的步骤如下:创建ROM镜像,此处为宏,定义在j2me_cldc/kvm/VmCommon/h/garbage.h初始化FPU初始化异步I/0系统初始化本地代码初始化vm,此处为宏,定义在j2me_cldc/kvm/VmUnix/h/machine_md.h初始化全局变量初始化性能统计的变...原创 2019-07-05 15:32:19 · 5114 阅读 · 0 评论 -
kvm启动流程-004
本文介绍kvm启动过程中的初始化class-path table,初始化VM所需要的内部类.初始化class-path table此处的代码如下:void InitializeClassLoading(){ char *classpath = UserClassPath; int length, pathCount, i; int tableIndex; ...原创 2019-07-05 12:31:49 · 5000 阅读 · 0 评论 -
kvm启动流程-003
kvm在启动时的步骤如下:创建ROM镜像,此处为宏,定义在j2me_cldc/kvm/VmCommon/h/garbage.h初始化FPU初始化异步I/0系统初始化本地代码初始化vm,此处为宏,定义在j2me_cldc/kvm/VmUnix/h/machine_md.h初始化全局变量初始化性能统计的变量,定义在 j2me_cldc/kvm/VmCommon/h/profiling....原创 2019-07-05 12:04:03 · 5138 阅读 · 0 评论 -
kvm启动流程-002
本文介绍初始化内存系统的代码.该方法定义如下:void InitializeMemoryManagement(void){ int index; gcInProgress = 0;// 是否gc在执行过程中 InitializeHeap(); // 1.初始化堆 // 2.初始化root index = 0; GlobalRoots[index...原创 2019-07-05 09:57:44 · 4969 阅读 · 0 评论 -
kvm启动流程
从本文开始介绍,kvn的启动流程.启动入口位于j2me_cldc/kvm/VmExtra/src/main.c的main方法.代码如下:int main (int argc, char* argv[]) { int result;#if USE_JAM char *jamInstalledAppsDir = "./instapps";#endif JamEnab...原创 2019-07-02 18:11:11 · 5873 阅读 · 0 评论 -
KVM源码解析目录
kvm 源码解析目录kvm目录结构kvm类加载-001,介绍类加载的初始化工作kvm类加载-002, loadRawClass介绍kvm类加载-003,加载常量池kvm类加载-004,加载类的标识符,加载接口kvm类加载-005,加载字段kvm类加载-006,加载方法kvm link解析StackMap属性解析kvm类加载-007kvm 验证-模拟字节码执行...原创 2019-07-01 18:11:30 · 4805 阅读 · 0 评论 -
kvm 验证-模拟字节码执行
上篇文章介绍了kvm进行验证的大部分过程.本文来介绍字节码执行的过程.kvm内部定义了枚举,来支持字节码的类型验证.代码如下:enum { ITEM_Bogus, /* 未使用 */ ITEM_Integer, ITEM_Float, ITEM_Double, ITEM_Long, ITEM_Null, /* acons...原创 2019-07-01 18:06:47 · 5272 阅读 · 0 评论 -
kvm类加载-007
之前的几篇文章介绍了将一个类从RAW到linked的过程.这里我们再次回顾一下kvm内部的class的状态:#define CLASS_RAW 0 /* this value must be 0 */#define CLASS_LOADING 1#define CLASS_LOADED 2#define CLASS_LINKED 3#define CLASS_...原创 2019-07-01 18:00:15 · 5127 阅读 · 0 评论 -
StackMap属性解析
由于我们会在后续的文章介绍class验证环节,其中在校验方法时需要使用到StackMap.那么什么是StackMap呢?从Java 6开始,JVM规范有一个更新文档,JSR 202,里面提到一种新的字节码校验算法,“类型检查”;在此之前是用“类型推导”的算法。为了支持新算法,Class文件从版本50开始添加了一个新的属性表,叫做StackMapTable,里面记录的是一个方法中操作数栈与局部变...原创 2019-07-01 17:59:12 · 7361 阅读 · 0 评论 -
kvm link解析
之前的几篇文章介绍了 kvm 将 class读取到kvm中的环节,此时该class的状态为CLASS_LOADED.此时其还需要进行链接,验证.本文介绍一下其链接环节.链接该部分的代码是在j2me_cldc/kvm/VmCommon/src/loader.c 中,代码如下:// 该代码为loadClassfile的一部分 // 1. 沿着类的继承体系,向上查找,找到位于继...原创 2019-07-01 17:57:58 · 5057 阅读 · 0 评论 -
kvm类加载-006
本文介绍kvm加载方法的部分.在jvm规范中,),包括实例初始化方法和类初始化方法(§2.9)在内,都由method_info结构所定义。在一个Class文件中,不会有两个方法同时具有相同的方法名和描述符(§ 4.3.3)。method_info结构格式如下:method_info { u2 access_flags; u2 name_index; u2 descriptor_ind...原创 2019-07-01 17:56:28 · 5015 阅读 · 0 评论 -
kvm类加载-005
本文讲述kvm加载字段的部分.在jvm规范中,每个字段(Field)都由field_info结构所定义,在同一个Class文件中,不会有两个字段同时具有相同的字段名和描述符.field_info结构格式如下:field_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_count; ...原创 2019-07-01 17:55:22 · 5006 阅读 · 0 评论 -
kvm类加载-004
这里再贴一下, loadRawClass 方法的步骤:打开对应的class文件加载版本号加载常量池加载类的标识符 <— 本文讲解该步骤.加载接口 <— 本文讲解该步骤.加载字段加载方法加载类的属性关闭流加载类的标识符在jvm规范中,支持的access_flags,如图:带有ACC_SYNTHETIC标志的类,意味着它是由编译器自己产生的而不是由程序员编写...原创 2019-07-01 17:53:17 · 4978 阅读 · 0 评论 -
kvm类加载-003
这里再贴一下, loadRawClass 方法的步骤:打开对应的class文件加载版本号加载常量池 <— 本文讲解该步骤.加载类的标识符加载接口加载字段加载方法加载类的属性关闭流常量池的数据结构常量池定义如下:struct constantPoolStruct { union constantPoolEntryStruct entries[1];...原创 2019-07-01 17:51:25 · 4957 阅读 · 0 评论 -
kvm类加载-002
本文介绍加载过程,在上文中类加载的准备环节。接下来,就会调用loadClassfile方法.将指定的类加载到kvm中,并且进行链接。注意,在load和link的过程中,是向上回溯进行的.解析load 涉及的代码如下: volatile INSTANCE_CLASS clazz = InitiatingClass; /* * 如果class的状态不是CLASS_RAW,...原创 2019-07-01 17:49:45 · 3989 阅读 · 0 评论 -
kvm类加载-001
开篇在JVM中,类加载的过程如图所示:加载,查找并加载类的二进制数据,在Java堆中也创建一个java.lang.Class类的对象。连接,连接又包含三块内容:验证、准备、初始化。验证,文件格式、元数据、字节码、符号引用验证;准备,为类的静态变量分配内存,并将其初始化为默认值;解析,把类中的符号引用转换为直接引用初始化,为类的静态变量赋予正确的初始值。而在kvm的实现...原创 2019-07-01 17:48:09 · 5144 阅读 · 2 评论