Java内存区域总结

运行时内存区域

	Java运行时内存区域分为两部分
		一部分线程不共享的包括 程序计数器,虚拟机栈,本地方法栈。
	 	一部分为线程共享的包括 方法区和堆。

图片来源深入理解Java虚拟机

程序计数器(Program Counter Register)

	保存当前线程执行的行号指示器,通过改变该计数器的值获取下一次需要运行的指令,若执行的是Java方
法则计数器保存的是正在执行的字节码指令位置,如果执行的是Native 本地方法则计数器为空。
	线程私有的数据,每个线程有独立的程序计数器,指向当前线程正在执行的位置,当线程挂起后被唤醒
则执行该计数器指向的位置。

虚拟机栈(Java Virtual Machine Stack)

	保存当前线程执行的Java方法的内存模型,每个Java方法被执行时创建一个栈帧,插入虚拟机栈,当方
法被执行完毕后,栈帧出栈。
	栈帧保存数据包括 局部变量表、操作数栈、动态连接、方法出口等信息。

本地方法栈

	保存当前线程执行的Native方法的内存模型,具体和虚拟机栈类似。

虚拟机栈和本地方法栈都会发生StackOverflowError和OutOfMemoryError异常。
如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果Java虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够的内存会抛出OutOfMemoryError异常

方法区

	保存已被虚拟机加载的类信息,常量池,静态变量,即时编译器(JIT)编译后的代码缓存等数据。是线
程共享的区域。

	几乎所有对象实例都分配在堆上,是线程共享的区域
	从垃圾收集器分代收集的方式来看,堆又可分为年轻代Eden和老年代Old Generation。
	从分配内存角度来看,堆会给每个内存分配一个线程私有的分配缓冲区(Thread Local Application 
Buffer)TLAB,提升分配效率。

直接内存

	不是运行时内存的一部分,直接内存大小不被堆大小所限制,会受到本机总内存限制。
	使用场合 申请次数少,读写频繁。

对象的创建和访问

	当虚拟机遇到一条创建对象的指令时,先去方法区查询此类是否已经被加载过,如果没有需要先对此类
进行类加载过程,然后在将创建对象分配到堆空间中。

类的加载过程

	类的加载分为以下7步,加载、验证、准备、初始化和卸载这五部都是按照前后顺序进行的,但是不一定
是前一部分完成后后一部分才开始,	例如加载开始后,但是还未完成时,验证已经开始了。解析过程可以在
初始化之后在开始。

在这里插入图片描述

加载

	通过类的全限定名获得类的二进制字节流,并将静态存储结构转化为方法区的存储结构,然后构建一个
代表这个类的java.lang.Class对象,作为方法区这个类的入口。

验证

	对字节流的验证,保证这些代码执行后,整个虚拟机是安全的。

准备

	为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值的阶段。
	如一个 static int value = 123; 在准备阶段完成后 value值为0而不是123。

解析

	将常量池内符号引用转化为直接引用。包括类或接口、字段、类方法、接口方法、方法类型、方法句柄
和调用点限定符这7类符号引用。
	符号引用例如 : int a = 0 ; 只是符号,而直接引用则是a指向0所在内存中的位置。

初始化

	初始化阶段就是执行类构造器<clinit>()方法的过程,<clinit>方法是虚拟机自动收集类变量赋值语句
和static代码块自动生成的一个方法。

深入理解Java虚拟机(周志明)阅读笔记,理解有限,如有错误还望指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值