java-doc-原理

JVM

运行时数据区

运行时数据区

运行时数据区

线程共享

所有线程能访问这块内存数据,随虚拟机或GC创建和销毁

线程独占

每个线程都会有它独立的空间,随线程生命周期而创建和销毁

方法区

作用:存储加载的类信息、常量、静态变量、JIT编译后的代码等数据

GC:

  • 方法区存在垃圾回收,但是回收频率很低;
  • 回收主要针对常量池的回收,和类型的卸载;
  • 当方法区无法满足内存时,报OOM(out of memory)。

堆内存

作用:唯一的目的就是存放对象实例,几乎所有的对象、数组都在这里存放

对于大多数应用来说,堆是JVM管理的内存中最大的一块内存区域,也是最容易OOM的区域

大多数JVM都将堆实现为大小可扩展的(通过-Xmx、-Xms控制)

引用算法

引用算法

引用算法

引用计数器算法:存在两个对象相互引用的问题

可达性分析算法:主力的商用程序语言(Java、C#)都是通过可达性分析算法来判断对象是否存活的,GC Roots可以是:

  • 虚拟机栈
  • 方法中静态属性引用的对象
  • 方法区中常量引用的对象
  • Native方法引用的对象

虚拟机栈

线程中方法执行的模型,每个方法执行时,就会在虚拟机栈中创建一个栈帧,每个方法从调用到执行的过程,就对应这栈帧在虚拟机栈中从入栈到出栈的过程。

栈帧:虚拟机栈由多个栈帧(Stack Frame)组成。一个线程会执行一个或多个方法,一个方法对应一个栈帧。

本地方法栈

和虚拟机栈功能类型,虚拟机栈是为虚拟机执行JAVA方法而准备的,本地方法栈是为虚拟机使用Native方法而准备的。

程序计数器

程序计数器(Program Counter Register)记录当前线程执行字节码的位置,字节码解析器工作时,就是通过改变计数器的值来选取下一条需要执行的字节码指令。

如果执行java方法,存储的是字节码指令地址,如果执行Native方法,则计数器值为空

程序计数器是唯一一个没有任何OOM的区域

直接内存

直接内存是不属于JVM内存区域,是我们常说的堆外内存。

Java引用NIO之后,可以使用Native函数库直接分配对外内存,然后通过一个存在Java堆中的DirectByteBuffer对象作为操作这块内存区域的引用进行操作。

直接内存不受java对大小的限制,当内存总和大于机器物理内存时,才会OOM。

Class文件

class文件包含JAVA程序执行的字节码;数据严格按照格式紧凑排列在class文件中的二进制流,中间无任何分隔符; u1、 u2、 u4、 u8都是无符号数,表示前面的多少个字节码(例如u2表示class文件中的2个字节码); info结尾都是表 。

全限定名

把类全名中的. 替换成/,例如org/fenixsoft/clazz/TestClass;

简单名称

是指没有类型和参数修饰的方法或者字段名称,如 public int inc(){} , 简单名称就是inc, public int age 字段,简单名称就是age

描述符

比较复杂,描述符的偶用是用来描述字段的数据类型、方法的参数列表(包括数量、类型以及顺序)和返回值。如“int[]” 将被标记为“[I”
java.lang.String[][] ,被标记为“[[Ljava/lang/String;”;
java.lang.String toString() 的描述符为()Ljava/lang/String