标签:main方法 分享 虚拟机 两种 stack 基础数据类型 mem add java多线程
按照Java虚拟机规范的规定, JVM自动管理的内存将包括以下几个运行时的数据区域:
下面分别对几个数据区域进行说明:
1.程序计数器
程序计数器是JVM中一块较小的内存区域, 保存着当前线程执行的虚拟机字节码指令的内存地址.
Java多线程的实现, 其实是通过线程间的轮流切换并分配处理器执行时间的方式实现的, 在任何时刻, 处理器都只会执行一个线程的指令. 在多线程场景下, 为了保证线程切换回来后, 还能恢复到原来的状态, 找到原先执行的指令, 所以每个线程都会设立一个程序计数器, 并且各个线程之间互不影响, 程序计数器为"线程私有"的内存区域.
若当前线程正在执行的是Java方法, 则程序计数器保存的是虚拟机字节码的内存地址, 若正在执行的Native方法(非Java方法), 则程序计数器为空.
程序计数器是唯一一个在Java规范中没有规定任何OutOfMemory(内存耗尽)场景的区域
2.虚拟机栈
虚拟机栈和线程是紧密联系的, 每创建一个线程就会对应创建一个Java栈, 生命周期和线程相同, 所有虚拟机栈也是"线程私有"的内存区域.
这个栈中对应多个栈帧, 每调用一个方法就会往栈中创建并压入一个栈帧, 栈帧是用来存储方法数据和部分过程结果的数据结构, 每一个方法从调用到最终返回结果的过程, 就对应一个栈帧从入栈到出栈的过程.
线程运行过程中, 只有一个栈帧处于活跃状态, 被称为"当前活动帧栈", 当前活动帧栈始终是虚拟机栈的栈顶元素.
在Java虚拟机规范中, 对这个区域规定了两种异常情况:
3.本地方法栈
本地方法栈和虚拟机栈的作用相似, 只是虚拟机栈是为Java方法服务的, 而本地方法栈是为Native方法服务的.
4.方法区
方法区是用来存储类结构信息(包括常量池、静态变量、构造函数等)的地方, 类型信息是由类加载器在类加载是从类文件中提取出来的
方法区存在着垃圾回收, 因为用户通过自定义加载器加载的一些类同样会成为垃圾, JVM会回收一个未被引用类所占的空间, 以使方法区的空间最小
方法区是线程共享的.
5.堆
堆是存储java实例或者对象的地方, 是GC的主要区域, 同样也是线程共享的内存区域.
下面举几个例子来说明:
上面的main方法中运行过程如下:
一、方法区、堆是线程共享的。 虚拟机栈、本地方法栈和程序计数器是线程私有的
二、栈中:
三、堆中:
四、方法区中:
标签:main方法 分享 虚拟机 两种 stack 基础数据类型 mem add java多线程
原文地址:https://www.cnblogs.com/hujingnb/p/10181616.html