摘要:
垃圾回收 垃圾收集的历史早在Java之前便已出现,1960年诞生于麻省理工学院的Lisp是第一门开始使用内存动态分配和垃圾收集技术的语言,其作者John McCarthy就思考过垃圾收集需要完成的三件事情: 哪些内存需要回收? 什么时候回收? 如何回收? 即便如今内存动态分配与内存回收技术已经相当成 阅读全文
摘要:
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。 这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。根据《Java虚拟机规范》 的规定,Java虚拟机所管理的内存将会包括以下几个 阅读全文
摘要:
动态代理 日常开发中,我们经常会遇到一些与我们业务无关却又无法避免的需求,比如:统计每个接口的访问量、给每个接口打印日志……等等,这些都是很常见的需求。如果在每个接口里编写增加访问量或者打印日志的代码,势必会引入一些冗余且无关业务的代码。 因此,Java提出动态代理的概念,将我们的主业务放在被代理类 阅读全文
摘要:
栈帧 每一次函数的调用,都会在调用栈(call stack)上创建并维护一个独立的栈帧(stack frame)。每个独立的栈帧一般包括:方法的局部变量表、动态链接信息、方法的返回地址以及操作数栈等信息。 动态链接是Java比较强大的一点,C++在编译期间就确定好类与类之间的关系,包括地址的偏移量等 阅读全文
摘要:
这一节,我们来分析下异常在字节码文件中的表现,我们来看一下MyTest3: package com.leolin.jvm.bytecode; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja 阅读全文
摘要:
之前分析的MyTest1程序是比较简单的程序,接来下我们将再用一个程序来巩固一下对JVM字节码的理解: package com.leolin.jvm.bytecode; public class MyTest2 { String str = "Welcome"; private int x = 5; 阅读全文
摘要:
接下来,就是分析MyTest1第二个方法,肯定不是int getA()就是void setA(int a)。在构造方法之后,我们读到了0x0001,这是一个访问标志为ACC_PUBLIC的方法,方法名的索引值为0x000e,类型描述符为0x000f,在常量池中分别对应getA和()I,所以我们能判定 阅读全文
摘要:
在分析完常量池后,我们来看下Java字节码的整体结构: 魔术码(Magic Number) 4个字节 版本(version) 2+2个字节 常量池(Constant pool) 2+n个字节 访问标志(Access flags) 2个字节 当前类(This Class Name) 2个字节 父类(S 阅读全文
摘要:
字节码 Java的规范分为两种,一种是Java语言规范,一种是虚拟机规范。Java语言规范主要集中在语言的层面上,虚拟机规范集中在更为底层的层面上。字节码属于Java虚拟机规范的一部分,我们知道在JVM上涌现出各种各样的语言,比如Scala、Groovy、kotlin等等,这些语言语法不尽相同,但编 阅读全文
摘要:
我们知道,每个类都会尝试使用自己的类加载器去加载依赖的类。如果ClassX引用ClassY,那么ClassX的类加载器会尝试加载ClassY,前提是ClassY尚未被加载。但这种做法有可能出现一个问题,如果一个根类加载器所加载的类,要去引用一个classpath下的类,是不是会出现问题?我们知道,c 阅读全文