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