你好,游客 登录 注册 搜索
背景:
阅读新闻

Java内存区域-“堆与栈”

[日期:2016-08-27] 来源:Linux社区  作者:yunheyj [字体: ]

  本文是我阅读周志明老师《深入理解Java虚拟机-JVM高级特性与最佳实战》章节2.2的学习笔记。更多内容,请参考原书。

  Java虚拟机在执行Java程序时会将其所管理的内存划分为若干个不同的数据区域,这些区域有各自的用途及生命周期。具体而言包括以下几个区域。

1. 程序计数器

  一块较小的内存空间,可视作当前线程所执行的字节码的行号指示器。主要用途是选取该线程下一条需要执行的字节码指令。

  每个线程有一个独立的程序计数器,各个线程的计数器之间互不影响,独立存储。这样的内存区域也被称为“线程私有”的内存。

  若线程在执行Java方法,则计数器记录正在执行的虚拟机字节码指令的地址;若正在执行Native方法,则计数器为“Undefined”。

2. 虚拟机栈

  同样是线程私有的,其生命周期与线程同步。虚拟机栈描述Java方法执行的内存模型,每个方法在执行时都会创建一个Stack Frame,其中存储了局部变量表,操作数栈,动态链接,方法出口等信息。每个方法从调用到执行完成的过程,即对应着一个Stack Frame在虚拟机栈中从入栈到出栈的过程。

  局部变量表存放编译器可知的各种基本数据类型,对象引用及Return Adress类型。局部变量表所需的内存空间在编译期间完成分配,也就是说进入一个方法时,其Stack Frame中的局部变量空间是确定的,在运行期间不会改变。

  当线程请求的栈深度大于虚拟机所允许的深度,即抛出“StackOverflowError”;若虚拟机可动态扩展(当前大部分虚拟机都可扩展),若扩展时无法申请到足够的内存,则抛出“OutOfMemoryError”。

3. 本地方法栈

  主要为虚拟机使用到的Native方法服务,其作用与虚拟机栈类似。

4. Java堆

  Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建,是虚拟机管理的内存中最大的一块。基本来说,所有的对象实例及数组都要在这里分配内存。某个对象分配的空间大小是另一个问题。

  Java堆是垃圾收集器管理的主要区域,因此很多时候也被称为“GC堆”(Garbage Collection Heap)。堆上各个区域的分配回收等是GC问题。

  Java堆只需是逻辑上连续的即可,不必物理上连续。目前主流的虚拟机都将堆实现成了可扩展的(-Xmx,-Xms,即最大堆和初始堆大小)。若堆需要扩展而无法扩展时,也会抛出“OutOfMemory-Error”。

5. 方法区

  Method Area也是被各个线程共享的内存区域,用去存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。逻辑上来说属于堆的一部分。

  关于方法区,运行时常量池及直接内存等的相关内容,请参考原书。

深入理解Java虚拟机:JVM高级特性与最佳实践 第2版 高清PDF+源码  下载 http://www.linuxidc.com/Linux/2014-09/106869.htm

本文永久更新链接地址http://www.linuxidc.com/Linux/2016-08/134653.htm

linux
相关资讯       Java栈  Java堆  Java内存区域 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款