《深入理解JAVA虚拟机》第二版 阅读笔记1

阅读这本书第一遍是在学习JAVA一年后,强制自己看完了,但是很多东西没看明白,现在接触JAVA快要三年了,是时候重啃此书了。

JAVA内存区域包括:
JAVA堆,方法区(永久带)
虚拟机栈,本地方法栈,程序计数器

第一行的两个是所有线程共享的区域
第二行的三个是每个线程独自拥有的

程序计数器表示当前线程执行到哪一行代码了,每个线程都记住自己的,CPU进行线程调度的时候一会执行A线程,一会停止A线程开始执行B线程,然后再回来执行A线程,每个线程都要记住自己的进度才能在从runnable到running状态的时候准确地继续运行。

虚拟机栈存放着执行方法需要的一些信息,其中最重要的是局部变量表,里面有方法用到的基本数据类型的值和对象类型的引用,开始执行一个方法时数据入栈,方法执行结束时数据出栈。当请求的栈深度大于虚拟机允许的深度,会报StackOverFlowError,如果虚拟机栈允许动态扩展,那么当扩展时发现无法申请到足够的内存,就会报OutOfMemoryError

本地方法栈和虚拟机栈差不太多,从字面上可以知道与执行Native方法有关

JAVA堆 众所周知JAVA的一大特点是可以自己管理内存,其实主要指的就是对java堆的垃圾回收(GC)操作,JAVA堆用来存放JAVA对象和数组,可想而知内存占用会比较多。不同的GC算法会将JAVA堆进一步划分为多个区域,例如:新生代和老年代。通过-Xmx和-Xms来配置堆的大小,当堆里的剩余内存不够放下示例且也无法再扩展时,会抛出OutOfMemoryError的错误

方法区存储了所有线程都可能会用到的东西,比如已经加载好的类信息,常量,静态变量,即时编译器编译好的代码等。方法区有一块区域叫运行时常量池,类加载好之后,会将编译过程中生成的字面变量和符号引用放入运行时常量池。除了类编译期间可以把值放入常量池之外,运行时也可能放入新的常量,例如String.intern()方法

直接内存 直接内存是不受JAVA虚拟机管理的,可以直接用代码申请的一段堆外内存,某些场景下可以提高效率,受本机内存大小的限制。

猜你喜欢

转载自blog.csdn.net/u010588262/article/details/81269490