JVM内存模型详解


1.内存模型图解

       Java虚拟机在执行Java程序的过程中,会把它所管理的内存划分为若干个不同的数据区。这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则依赖用户线程的启动和结束而建立和销毁,我们可以将这些区域统称为Java运行时数据区域。如下图是一个内存模型的关系图:



如上图所示,Java虚拟机运行时数据区域被分为五个区域:(Heap)、栈(Stack)、本地方法栈(Native Stack)、方法区(Method Area)、程序计数器(Program Count Register)。


2.堆(Heap)

  对于大多数应用来说,Java Heap是Java虚拟机管理的内存的最大一块,这块区域随着虚拟机的启动而创建。在实际的运用中,我们创建的对象数组就是存放在堆里面。如果你听说线程安全的问题,就会很明确的知道Java Heap是一块共享的区域,操作共享区域的成员就有了锁和同步。

  与Java Heap相关的还有Java的垃圾回收机制(GC),Java Heap是垃圾回收器管理的主要区域。程序猿所熟悉的新生代、老生代、永久代的概念就是在堆里面,现在大多数的GC基本都采用了分代收集算法。如果再细致一点,Java Heap还有Eden空间,From Survivor空间,To Survivor空间等。

Java Heap可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。


3.栈(Stack)

   相对于Java Heap来讲,Java Stack是线程私有的,她的生命周期与线程相同。Java Stack描述的是Java方法执行时的内存模型,每个方法执行时都会创建一个栈帧(Stack Frame)用语存储局部变量表操作数栈动态链接方法出口等信息。从下图从可以看到,每个线程在执行一个方法时,都意味着有一个栈帧在当前线程对应的栈帧中入栈和出栈。

图中可以看到每一个栈帧中都有局部变量表。局部变量表存放了编译期间的各种基本数据类型,对象引用等信息。


4.本地方法栈(Native Stack)

   本地方法栈(Native Stack)与Java虚拟机站(Java Stack)所发挥的作用非常相似,他们之间的区别在于虚拟机栈为虚拟机栈执行java方法(也就是字节码)服务,而本地方法栈则为使用到Native方法服务。


5.方法区(Method Area)

   方法区(Method Area)与堆(Java Heap)一样,是各个线程共享的内存区域,它用于存储虚拟机加载的类信息常量静态变量即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是她却有一个别名叫做非堆(Non-Heap)。分析下Java虚拟机规范,之所以把方法区描述为堆的一个逻辑部分,应该觉得她们都是存储数据的角度出发的。一个存储对象数据(堆),一个存储静态信息(方法区)

   在上文中,我们看到堆中有新生代、老生代、永久代的描述。为什么我们将新生代、老生代、永久代三个概念一起说,那是因为HotSpot虚拟机的设计团队选择把GC分代收集扩展至方法区,或者说使用永久代来实现方法区而已。这样HotSpot的垃圾收集器就能想管理Java堆一样管理这部分内存。简单点说就是HotSpot虚拟机中内存模型的分代,其中新生代和老生代在堆中,永久代使用方法区实现。根据官方发布的路线图信息,现在也有放弃永久代并逐步采用Native Memory来实现方法区的规划,在JDK1.7HotSpot中,已经把原本放在永久代的字符串常量池移出。


6.总结

1、 线程私有的数据区域有:

              Java虚拟机栈(Java Stack

    本地方法栈(Native Stack

2、 线程共有的数据区域有:

    堆(Java Heap

             方法区





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值