2019独角兽企业重金招聘Python工程师标准>>>

在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认识Stack和Heap,并通过这些原理认清Java中静态方法和静态属性的问题。
    一般,JVM的内存分为两部分:Stack和Heap。
    Heap(堆)是JVM的内存数据区。Heap 的管理很复杂,每次分配不定长的内存空间,专门用来保存对象的实例。在Heap 中分配一定 的内存来保存对象实例,实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是 指令,保存在Stack中),在Heap 中分配一定的内存保存对象实例和对象的序列化比较类似。而对象实例在Heap 中分配好以后,需要 在Stack中保存一个4字节的Heap 内存地址,用来定位该对象实例在Heap 中的位置,便于找到该对象实例。

Stack的内存管理是顺序分配的,而且定长,不存在内存回收问题;而Heap 则是随机分配内存,不定长度,存在内存分配和回收 的问题;因此在JVM中另有一个GC进程,定期扫描Heap ,它根据Stack中保存的4字节对象地址扫描Heap ,定位Heap 中这些对象,进 行一些优化(例如合并空闲内存块什么的),并且假设Heap 中没有扫描到的区域都是空闲的,统统refresh(实际上是把Stack中丢 失了对象地址的无用对象清除了)。

我们首先要搞清楚的是什么是数据以及什么是指令。然后要搞清楚对象的方法和对象的属性分别保存在哪里。
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数据内存区。

转载于:https://my.oschina.net/javazhang/blog/136888

JVM中的Stack和Heap1相关推荐

  1. 深入Java虚拟机:JVM中的Stack和Heap

    http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/gc-Stack.html 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里 ...

  2. JVM中栈的frames详解

    文章目录 简介 JVM中的栈 Frame Local Variables本地变量 Operand Stacks Dynamic Linking动态链接 方法执行完毕 简介 我们知道JVM运行时数据区域 ...

  3. JVM中可生成的最大Thread数量

    最近想测试下Openfire下的最大并发数,需要开大量线程来模拟客户端.对于一个JVM实例到底能开多少个线程一直心存疑惑,所以打算实际测试下,简单google了把,找到影响线程数量的因素有下面几个: ...

  4. 详解JVM内存管理与垃圾回收机制3 - JVM中对象的内存布局

    在Java语言层面,可以通过Class类来描述普通的Java类,当JVM创建对象的同时,会生成对应的Class对象,用来描述此对象的大致模型,这也是反射的基础.那么在JVM的内部是如何描述一个普通的对 ...

  5. 追踪JVM中的本地内存

    点击蓝色"程序猿DD"关注我 回复"资源"获取独家整理的学习资料! 转载自公众号:锅外的大佬 1.概述 有没有想过为什么Java应用程序通过众所周知的-Xms和 ...

  6. java中堆栈(stack)和堆(heap)

    http://www.ej38.com/showinfo/java-172156.html 堆栈是一种先进后出的数据结构,只能在一端进行输入或输出数据的操作  Stack类在java.util包中 向 ...

  7. JVM中的五大内存区域划分详解

    一.快速扫盲 1. JVM是什么 JVM是Java Virtual Machine的缩写,即咱们经常提到的Java虚拟机.虚拟机是一种抽象化的计算机,有着自己完善的硬件架构,如处理器.堆栈等,具体有什 ...

  8. java 内存跟踪_详解JVM中的本机内存跟踪

    1.概述 有没有想过为什么Java应用程序通过众所周知的-Xms和-Xmx调优标志消耗的内存比指定数量多得多?出于各种原因和可能的优化,JVM可以分配额外的本机内存.这些额外的分配最终会使消耗的内存超 ...

  9. jvm中方法区和常量池详解_JVM——内存区域:运行时数据区域详解

    关注微信公众号:CodingTechWork,一起学习进步. 引言 我们经常会被问到一个问题是Java和C++有何区别?我们除了能回答一个是面向对象.一个是面向过程编程以外,我们还会从底层内存管理和垃 ...

最新文章

  1. IAR实际使用过程中遇到的问题
  2. 在.NET中不安装Office使用EPPlus生成带图表(Chart)的Excel报表
  3. 实现Android-JNI本地C++调试
  4. ubuntu Qt Creator不能输入中文
  5. windows中使用mysql配置my.ini时的坑
  6. 一加8渲染图曝光:后置三摄/五种配色可选
  7. html怎么做成3d正方体,利用CSS3的3D效果制作正方体
  8. Spring Boot最核心的21个注解
  9. spring或springmvc自动生成applicationcontext.xml或springmvc文件(此文转载和借鉴多篇文章)...
  10. 超级灰色按钮克星更新v1.3.1112.40
  11. matlab不用hist画直方图,matlab可以画直方图
  12. 百度图像识别java使用笔记
  13. 记录:The field files exceeds its maximum permitted size of 1048576 bytes...解决方案【亲测有效】
  14. sigmoid函数导数的硬件实现(verilog)
  15. 使用C++代码解密微信加密数据库信息!
  16. daifloil demnum grease daikin DG203
  17. 然而沼跃鱼早就看穿了一切 hihoCoder1082
  18. 彻底弄懂泰勒近似,泰勒展开由来
  19. wgt文件怎么安装到手机_安卓wgt安装
  20. C#获取注册表指定键值

热门文章

  1. ID vs Class 老生常谈的选择器问题
  2. python方法和函数的格式是完全一样的_Python成为专业人士笔记-返回变量形式函数- str() 和 repr()...
  3. java菜单实现功能_Java实现超市库存管理系统
  4. junction.exe 放在哪_情侣拥抱的5种姿势,可以看出感情深浅,你们属于哪一种?...
  5. AWS — AWS Direct Connect
  6. C 语言编程 — 基本语法
  7. Windows XP中安装虚拟网卡microsoft loopback adapter
  8. BLOCK层基本概念:bio,request,request_queue
  9. R语言修改标题、坐标轴刻度、坐标轴名称的大小(cex.axis、cex.lab、cex.main函数)...
  10. SendTextMessage 等方便的消息发送函数