快速串讲——JVM内存的区域划分
【摘要】 目的快速定位JVM内存泄漏或者溢出等问题。面试基础题,加分项。 程序计数器(Program Counter Register)记录当前线程所执行的字节码的行号。依赖其实现分支、循环、跳转、异常处理、线程恢复。Natvie 方法时,其的值就为空。Java 虚拟机规范中唯一没有规定内存溢出的区域。“线程私有”的内存区域。 虚拟机栈(Virtual Machine Stacks)其生命周期与线程...
目的
- 快速定位JVM内存泄漏或者溢出等问题。
- 面试基础题,加分项。
程序计数器(Program Counter Register)
- 记录当前线程所执行的字节码的行号。
- 依赖其实现分支、循环、跳转、异常处理、线程恢复。
- Natvie 方法时,其的值就为空。
- Java 虚拟机规范中唯一没有规定内存溢出的区域。
- “线程私有”的内存区域。
虚拟机栈(Virtual Machine Stacks)
- 其生命周期与线程相同。
- 存储局部变量表、操作数栈、动态链接、方法出口等信息。
- 方法被执行的时候创建一个栈帧并入栈。
- 方法执行完成的时候对应栈帧出栈。
- 栈的深度过大时,抛出 StackOverflowError 。
- 线程数过多时,抛出 OutOfMemoryError 。
- “线程私有”的内存区域。
本地方法栈(Native Method Stacks)
- 为虚拟机使用到的 Native 方法服务。
- 栈的深度过大时,抛出 StackOverflowError 。
- 线程数过多时,抛出 OutOfMemoryError 。
- “线程私有”的内存区域。
堆(Java Heap)
- 用于存放对象实例,是JVM占用内存最大一块区域。
- 垃圾收集器管理的主要区域。
- 使用分代收集算法时,堆被细分为新生代和老年代,新生代再细分为Eden空间、 From Survivor 空间、 To Survivor 空间。
- 在HotSpot虚拟机中,通过-Xmx和-Xms控制堆的大小,通过-Xmn控制新生代的大小。
- 堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。
- 没有内存完成实例分配时,抛出 OutOfMemoryError 。
- “线程共享”的内存区域,线程共享的堆中又可能划分出多个线程私有的分配缓存区(Thread Local Allocation Buffer,TLAB)。
方法区(Method Area)
- 存储已被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码。
- 回收目标主要是针对常量池的回收和对类型的卸载。
- 可以选择不实现垃圾收集。
- 当方法区无法满足内存分配需求时,将抛出 OutOfMemoryError 。
- JDK6 使用永久代实现方法区。
- JDK7 中永久代的字符串常量池被移出。
- JDK8 使用元空间实现方法区。
- “线程共享”的内存区域。
总结
- 程序计数器:当前线程所执行的字节码的行号指示器。
- 虚拟机栈:Java方法执行的内存模型,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
- 本地方法栈:本地方法执行的内存模型,和虚拟机栈非常相似,其区别是本地方法栈为 JVM 使用到的 Native 方法服务。
- 堆:用于存储对象实例,是垃圾收集器管理的主要区域。
- 方法区:用于存储已被JVM加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
文章持续更新,微信搜索「万猫学社」第一时间阅读。
关注后回复「电子书」,免费获取12本Java必读技术书籍。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)