http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/gc-Stack.html

在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题。

  一般,JVM的内存分为两部分:Stack和Heap。

  Stack(栈)是JVM的内存指令区。Stack管理很简单,push一定长度字节的数据或者指令,Stack指针压栈相应的字节位移;pop一定字节长度数据或者指令,Stack指针弹栈。Stack的速度很快,管理很简单,并且每次操作的数据或者指令字节长度是已知的。所以Java 基本数据类型,Java 指令代码,常量都保存在Stack中。

  Heap(堆)是JVM的内存数据区。Heap 的管理很复杂,每次分配不定长的内存空间,专门用来保存对象的实例。在Heap 中分配一定的内存来保存对象实例,实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是指令,保存在Stack中),在Heap 中分配一定的内存保存对象实例和对象的序列化比较类似。而对象实例在Heap 中分配好以后,需要在Stack中保存一个4字节的Heap 内存地址,用来定位该对象实例在Heap 中的位置,便于找到该对象实例。

  由于Stack的内存管理是顺序分配的,而且定长,不存在内存回收问题;而Heap 则是随机分配内存,不定长度,存在内存分配和回收的问题;因此在JVM中另有一个GC进程,定期扫描Heap ,它根据Stack中保存的4字节对象地址扫描Heap ,定位Heap 中这些对象,进行一些优化(例如合并空闲内存块什么的),并且假设Heap 中没有扫描到的区域都是空闲的,统统refresh(实际上是把Stack中丢失了对象地址的无用对象清除了),这就是垃圾收集的过程;关于垃圾收集的更深入讲解请参考51CTO之前的文章《JVM内存模型及垃圾收集策略解析》。


JVM的体系结构

  我们首先要搞清楚的是什么是数据以及什么是指令。然后要搞清楚对象的方法和对象的属性分别保存在哪里。

  1)方法本身是指令的操作码部分,保存在Stack中;

  2)方法内部变量作为指令的操作数部分,跟在指令的操作码之后,保存在Stack中(实际上是简单类型保存在Stack中,对象类型在Stack中保存地址,在Heap 中保存值);上述的指令操作码和指令操作数构成了完整的Java 指令。

  3)对象实例包括其属性值作为数据,保存在数据区Heap 中。

  非静态的对象属性作为对象实例的一部分保存在Heap 中,而对象实例必须通过Stack中保存的地址指针才能访问到。因此能否访问到对象实例以及它的非静态属性值完全取决于能否获得对象实例在Stack中的地址指针。

  非静态方法和静态方法的区别:

  非静态方法有一个和静态方法很重大的不同:非静态方法有一个隐含的传入参数,该参数是JVM给它的,和我们怎么写代码无关,这个隐含的参数就是对象实例在Stack中的地址指针。因此非静态方法(在Stack中的指令代码)总是可以找到自己的专用数据(在Heap 中的对象属性值)。当然非静态方法也必须获得该隐含参数,因此非静态方法在调用前,必须先new一个对象实例,获得Stack中的地址指针,否则JVM将无法将隐含参数传给非静态方法。

  静态方法无此隐含参数,因此也不需要new对象,只要class文件被ClassLoader load进入JVM的Stack,该静态方法即可被调用。当然此时静态方法是存取不到Heap 中的对象属性的。

  总结一下该过程:当一个class文件被ClassLoader load进入JVM后,方法指令保存在Stack中,此时Heap 区没有数据。然后程序技术器开始执行指令,如果是静态方法,直接依次执行指令代码,当然此时指令代码是不能访问Heap 数据区的;如果是非静态方法,由于隐含参数没有值,会报错。因此在非静态方法执行前,要先new对象,在Heap 中分配数据,并把Stack中的地址指针交给非静态方法,这样程序技术器依次执行指令,而指令代码此时能够访问到Heap 数据区了。

  静态属性和动态属性:

  前面提到对象实例以及动态属性都是保存在Heap 中的,而Heap 必须通过Stack中的地址指针才能够被指令(类的方法)访问到。因此可以推断出:静态属性是保存在Stack中的,而不同于动态属性保存在Heap 中。正因为都是在Stack中,而Stack中指令和数据都是定长的,因此很容易算出偏移量,也因此不管什么指令(类的方法),都可以访问到类的静态属性。也正因为静态属性被保存在Stack中,所以具有了全局属性。

  在JVM中,静态属性保存在Stack指令内存区,动态属性保存在Heap数据内存区。

深入Java虚拟机:JVM中的Stack和Heap相关推荐

  1. [二]Java虚拟机 jvm内存结构 运行时数据内存 class文件与jvm内存结构的映射 jvm数据类型 虚拟机栈 方法区 堆 含义...

    前言简介 class文件是源代码经过编译后的一种平台中立的格式 里面包含了虚拟机运行所需要的所有信息,相当于 JVM的机器语言 JVM全称是Java Virtual Machine  ,既然是虚拟机, ...

  2. 【深入Java虚拟机JVM 04】JVM内存溢出OutOfMemoryError异常实例

    说明:文章所有内容均摘自<深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)> 在Java虚拟机规范的描述中,除了程序计数器外,虚拟机内存的其他几个运行时区域都有发生OutOfMe ...

  3. 【深入Java虚拟机JVM 03】Java内存模型

    说明:文章所有内容均摘自<深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)> Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的"高墙",墙外面的 ...

  4. 深入理解java虚拟机JVM(上)

    深入理解java虚拟机JVM(上) 链接:https://pan.baidu.com/s/1c6pZjLeMQqc9t-OXvUM66w 提取码:uwak 复制这段内容后打开百度网盘手机App,操作更 ...

  5. Java虚拟机JVM的内存管理

    Java虚拟机JVM的内存管理 关键词 一.JVM整体架构 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法区.程序计数器.本地方法栈五个部分. 名称 作用 特征 配置参数 异常 程序计数器 ...

  6. Java虚拟机JVM简介与理解(三)

    Java虚拟机JVM简介与理解(三) 问题背景 PC程序计数器 虚拟机栈 本地方法栈 堆 元空间 方法区 运行时常量池 直接内存 Lyric: 彻底把我囚禁在你的呼吸 问题背景 Java虚拟机JVM简 ...

  7. Java虚拟机-JVM

    Java内存模型 为什么说java是跨平台语言 所谓跨平台性,是指java语言编写的程序,一次编译后,可以在多个系统平台上运行; 实现原理:Java程序是通过java虚拟机在系统平台上运行的,只要该系 ...

  8. Java 虚拟机(JVM)原理介绍

    Java 虚拟机[JVM]原理介绍 1.概述 2.Java类的加载原理机制 2.1 .Java类的加载过程 2.2 .Class loader (类加载器) 2.2.1 类的生命周期 2.2.1.1 ...

  9. Java虚拟机内存的堆区(heap),栈区(stack)和静态区(static/method)

    JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 堆区: 1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指 ...

最新文章

  1. PostCSS原理解析
  2. 使用Java 8 Optional避免空指针异常
  3. 《BI那点儿事》三国人物智力分布状态分析
  4. Spring Aop——给Advice传递参数
  5. android 引用非 android 工程,Unity3D调用android方法(非插件方式)
  6. C++ 一个字符串只包含K和D。K表示杀人,D表示死亡。计算连续杀敌次数,阵亡则归零。
  7. identcurrent mysql_MYSQL库内所有表名及表结构获取
  8. UVA1585 LA3354 Score【水题】
  9. 函数重载函数的引用算重载吗_了解C ++中的函数重载
  10. 通过vba代码将word转换为PDF
  11. mysql多主集群_MYSQL-galera多主集群
  12. 腾达Tenda 路由器后门分析
  13. 海外RPA企业盘点:谁是领导者,谁是挑战者?
  14. 黑色商务中国风禅茶一味产品宣传介绍PPT模板
  15. AI 编辑视频!这特效太逆天了!代码开源 SIGGRAPH Asia 2021
  16. Java实现一个简易联网坦克对战小游戏
  17. VJ 1115 火星人
  18. 织梦免费网站模板手机端无法更新的原因及解决
  19. 《深度学习》之 目标检测 最全详解 (一)
  20. Nginx缓存、静态文件缓存配置

热门文章

  1. 关于浏览器跨域请求的相关原理实现--很经典的博客
  2. 最新综述:用于组合优化的强化学习
  3. 小马智行Pony.ai 2020校招宣讲行程来了!
  4. EMNLP2018论文解读 | 利用篇章信息提升机器翻译质量
  5. 超详细解读:神经语义解析的结构化表示学习 | 附代码分析
  6. paramterType和resultType的区别
  7. linux通过命令行本地目录取消svn关联
  8. JAVA——Tess4J简单的图像识别DEMO
  9. Even Number Theory
  10. 【练习】c++单向链表求交集