一。程序计数器
可以看做是当前线程所执行的字节码的行号指示器。
由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器 只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器, 各条线程之间的程序计数器互不影响,独立存储,称这类内存区域为“线程私有”的内存。
如果线程正在执行的是一个java方法,这个计数器记录的正在执行的虚拟机字节码指令的地址。
如果正在执行的是native方法,这个计数器值则为空。 undefined
此内存区域是唯一一个在java虚拟规范中没有规定任何OutOfMemoryError情况的区域
二。虚拟机栈(栈内存)
java线程私有,虚拟机栈描述的是java方法执行的内存模型。
每个方法在执行的时候,都会创建一个栈帧用于存储局部变量、操作数、动态链接、方法出口等信息。
每个方法调用都意味着一个栈帧在虚拟机栈中入栈到出栈的过程。
三、本地方法栈
和java虚拟机栈的作用类似。区别是该区域为JVM提供使用Native方法的服务。(此处算作是有亲身体验,接触的物联网项目调用C的.dll类库,使用的JNA也是半知半解算是对底层感兴趣的起源,因为老是遇到内存的问题【笑哭】)
四、堆内存
所有线程共享的一块区域,唯一作用就是存放对象实例。所有的对象实例及数组,都需要在堆中分配内存,垃圾回收器管理的主要区域。
目前主要垃圾回收算法都是分代收集算法,所以java堆中还可以细分为:新生代和老年代,再细致一点的还有eden区,from survivor、to survivor,默认情况下是8:1:1的比例。
根据java虚拟机规范的规定,java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可,就像我们的磁盘一样。
五、方法区
各个线程共享的一个区域,用于存储虚拟机加载的类信息,常量、静态变量,即时编译器编译后的代码等数据。
虽然虚拟机规范中把方法区描述成堆的一个逻辑部分,但是他却有一个别名叫Non-heap 非堆,目的是为了与java堆区分开来。
运行时常量池。是方法区的一部分,用于存放编译器生成的各种字面量和符号引用。
参考链接(大神分析的很全面):https://blog.csdn.net/Simba_cheng/article/details/82919792
参考链接:https://www.cnblogs.com/yangqiong1989/p/10665402.html
努力理解中......