Java内存区域总结(堆、栈、方法区等)

  • 如果线程正在执行的是一个 Java 方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是 Native 方法,这个计数器值则为空(Undefined)。

  • 此内存区域是唯一一个在 Java 虚拟机中没有规范任何 OutOfMemoryError 情况的区域。

2. Java 虚拟机栈


  • Java 虚拟机栈也是线程私有的,它的生命周期与线程相同(随线程而生,随线程而灭)

  • 如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;

  • 如果虚拟机栈可以动态扩展,如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常;(当前大部分 JVM 都可以动态扩展,只不过 JVM 规范也允许固定长度的虚拟机栈)

  • Java 虚拟机栈描述的是 Java 方法执行的内存模型:每个方法执行的同时会创建一个栈帧。 对于我们来说,主要关注的 stack 栈内存,就是虚拟机栈中局部变量表部分。

局部变量表

定义

局部变量表(Local Variable Table)是一组变量值存储空间,用于存放方法参数方法内部定义的局部变量

编译器确定容量

在Java程序编译为class文件时,就在方法的Code属性的 max_locals 数据项中确定了 该方法所需要分配的局部变量表的最大容量。

最小单位为变量槽(Slot)

一个Slot 可以存放一个32位以内的数据类型,包括基本数据类型 (boolean、byte、char、short、int、float、long、double)「String 是引用类型」,对象引用 (reference 类型) 和 returnAddress 类型(它指向了一条字节码指令的地址)。

3. 本地方法栈


与JVM栈区别

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

自由实现

Java 虚拟机规范对本地方法栈使用的语言、使用方法与数据结构并没有强制规定,因此可以由虚拟机自由实现。例如:HotSpot 虚拟机直接将本地方法栈和虚拟机栈合二为一。

异常

同虚拟机栈相同,Java 虚拟机规范对这个区域也规定了两种异常情况StackOverflowError 和 OutOfMemoryError异常。

4. 堆


  • 对于大多数应用来说,Java 堆 (Java Heap) 是 JVM所管理的内存中最大的一块。

  • Java 堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。

  • 此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

  • 数组引用变量是存放在内存中,数组元素是存放在内存中。

  • Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称作为 “GC 堆”。

  • 从内存回收的角度看,Java 堆中还可以细分为: 新生代老年代

  • 程序新创建的对象都是从新生代分配内存,新生代由 Eden Space 和两块相同大小的 Survivor Space(通常又称 S0 和 S1 或 From 和 To) 构成。

  • 详见JVM常见参数设置

  • 从内存分配角度,线程共享的 Java 堆可能划分出多个线程私有的分配缓冲区(TLAB)。

  • Java 堆可以处于物理不连续的内存空间中,只要逻辑是连续的即可,就像我们的磁盘空间一样。

  • 在实现时,即可以实现成固定大小的,也可以是可扩展的,不过当前主流的虚拟机都是按照可扩展来实现的 (通过 -Xmx 和 -Xms 控制)。

  • 如果堆上没有内存完成实例分配,并且堆也无法再扩展时,将会抛出 OutOfMemoryError异常。

5. 方法区


  • 方法区 (Method Area) 与 Java 堆一样, 是各个线程共享的内存区域。

  • 它用于存储已经被虚拟机加载的类信息常量静态变量即时编译器编译后的代码等数据

  • 运行时常量池 (Runtime Constant Pool) 是方法区的一部分。

  • 虽然 JVM规范把方法区描述为堆的一个逻辑部分, 但是它却又一个别名叫做 Non-Heap(非堆), 目的应该是与 Java 堆区分开来.

  • 方法区 和 永久代(Permanent Generation), 本质上两者并不相等。

仅仅是因为 HotSpot 虚拟机的设计团队选择把 GC 分代收集扩展至方法区, 或者说使用永久代来实现方法区而已。

这样 HotSpot 的垃圾收集器可以像管理 Java 堆一样管理这部分内容, 能够省去专门为方法区编写内存管理代码的工作。

因此, 对于 HotSpot 虚拟机, 根据官方发布的路线图信息, 现在也有放弃永久代并逐步采用 Native Memory 来实现方法区的规划了, 在目前已经发布的 JDK1.7 的 HotSpot 中, 已经把原本放在永久代的字符串常量池移出

  • JVM规范对方法区的限制非常宽松

和堆一样, 允许固定大小, 也允许可扩展的大小, 还可以选择不实现垃圾回收。 相对而言, 垃圾收集行为在这个区域是比较少出现的, 但是并非数据进入了方法区就如同进入永久代的名字一样” 永久” 存在了。

这区域的内存回收目标主要是针对常量池的回收和对类型的卸载, 一般来说, 这个区域的回收” 成绩” 比较难以令人满意, 尤其是对类型的卸载, 条件相当苛刻, 但是这部分区域的回收确实是存在必要的。

在 Sun 公司的 BUG 列表里, 曾出现过的若干个严重的 BUG 就是由于低版本的 HotSpot 虚拟机对此区域未完全回收而导致内存泄漏

  • 当方法区无法满足内存分配需求时, 将抛出 OutOfMemoryError 异常。

内存泄露和内存溢出

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。

image

上述的面试题答案都整理成文档笔记。 也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)

image

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
中…(img-mSl6gK2l-1713130386854)]

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 14
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值