1、程序计数器(线程私有):线程执行字节码的行号指示器(注意是字节码,本地方法计数器为空的)
2、Java虚拟机栈(线程私有):
(1)描述的是Java方法执行的内存模型
(2)每一个方法对应一个栈帧
(3)栈帧包含:局部变量表、操作数栈、动态链接、方法出口
(4)局部变量表包含:基本数据类型、对象引用、returnAddress类型
(5) 局部变量表slot会复用,导致一些对象不能被及时的回收,所以建议对象不用之后要赋值为空;







(6)局部变量表在编译器就已经完成分配
(7)动态链接指的是方法区中的常量池中 的符号引用在第一次运行期间转化为直接引用,这部分引用就称为动态链接
(8)方法的返回地址即方法出口有二:正常完成方法(如有返回值则是return的地方)、
方法异常时异常块(如果没有finally的情况下)
public void clear() { // 此处若有参数,参数也属于局部变量表
Node[] tab; // tab 是 对象引用
modCount++; // ++ 是在操作数栈中 modCount属于类实例的属性值,在堆中
if ((tab= table) != null && size> 0) {
size= 0;
for (int i= 0; i< tab.length; ++i)
tab[i] = null;
}
// 这里是方法出口
}
(9)会有两种异常:StackOverFlowError OutOfMemoryError
3、本地方法栈(线程私有):抛异常如Java虚拟机栈,不过是服务于本地方法的
4、Java堆(线程共享):
(1)几乎所有的实例都在这里分配内存(因为JIT和逃逸技术发展导致了不是绝对的所有)
(2)只会抛出OutOfMemoryError
5、方法区(线程共享):
(1)存储 已被虚拟机加载的类信息(即每个类的class类)、常量、静态变量、即时编译后的代码(第一次编译后的代码)
(2)只抛出OutOfMemoryError
6、运行时常量池(属于方法区的一部分):
(1)存放编译期的字面量和符号引用;
字面量:String str="abc" 中的"abc" int i = 1;中的 1
符号引用:就是类引用(类的全路径)
(2)String类中intern()方法就是运行期间将新的常量放入池中,class文件的动态性及并不是只有在编译期产生常量
7、直接内存:
(1)NIO中使用native方法直接分配堆外内存
(2)使用Java堆中的DirectByteBuffer对象作为这块引用进行操作
网友评论