1.jvm结构说明
jdk1.7: jdk1.8
1.8同1.7比,差别是:元数据区取代了永久代。
元空间的本质和永久代类似,都是对JVM规范中方法区的实现。
元空间与永久代区别:元数据空间并不在虚拟机中,而是使用本地内存。
参考文档:https://blog.csdn.net/weixin_43767015/article/details/105187313
1. 程序计数器
程序计数器 内存小,看作当前线程所执行的字节码的行号指示器,又称PC寄存器。
每个线程启动的时候,都会创建一个程序计数器。
字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,
分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
2. Java虚拟机栈
线程私有,每个线程对应一个Java虚拟机栈,其生命周期与线程同进同退。
每个Java方法在被调用的时候都会创建一个栈帧,并入栈。一旦完成调用,则出栈。所有的的栈帧都出栈后,线程也 就完成了使命。
StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度。
OutOfMemoryError:如果虚拟机栈可以动态扩展,而扩展时无法申请到足够的内存。
1.3 本地方法栈 ( Stack)
功能与Java虚拟机栈十分相同。区别在于,本地方法栈为虚拟机使用到的native方法服务。不多说。
虚拟机栈为虚拟机执行Java方法(字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。
1.4 堆(Java Heap)
Java堆是jvm内存管理的最大的一块区域,目的就是存放对象的实例,
在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会拋出OutOfMemoryError异常。
1.5方法区(jdk1.7特有的,方法区就是永久代)
方法区是被线程共享的区域。存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码、运行时常量池(逻辑包含字符串常量池)等
1. 8,字符串常量池从永久代中剥离出来,存放在堆中。
1.5. 元数据区(jdk1.8特有的)
元数据区取代了1.7版本及以前的永久代。
元空间与永久代区别:元数据空间并不在虚拟机中,而是使用本地内存。
元数据区和永久代本质上都是方法区的实现。方法区存放虚拟机加载的类信息,静态变量,常量等数据。
1.6. 直接内存
jdk1.4引入了NIO,它可以使用Native函数库直接分配堆外内存
2.方法区的演进细节
3.垃圾回收机制
内存泄漏:是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出。
内存溢出:指程序申请内存时,没有足够的内存供申请者使用,内存不够用,此时就会报错OOM,即所谓的内存溢出。
回收算法:参考文档:https://blog.csdn.net/wuzhixiu007/article/details/80116560