《深入理解 Java 虚拟机》学习笔记 -- 内存区域
《深入理解 Java 虚拟机》学习笔记 -- 内存区域
运行时数据区域
主要分为 6 部分:
- 程序计数器
- 虚拟机栈
- 本地方法栈
- Java 堆
- 方法区
如图所示:

1. 程序计数器(线程私有)
- 程序计数器是当前线程所执行字节码的行号指示器
- 字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令
- 为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器
- 执行 Java 方法,计数器记录的是正在执行的虚拟机字节码指令的地址;执行的是 Native 方法,计数器为空
- 程序计数器是唯一一个在 Java 虚拟机中不会出现
OutOfMemoryError情况的区域
2. Java 虚拟机栈(线程私有)
- 每个方法被执行的时候都会同时创建一个栈帧
- 每一个方法被调用直至执行完成的过程,就对应者一个栈帧再虚拟机中从入栈到出战的过程
- ”栈内存“指的就是虚拟机栈中的局部变量表部分
- 局部变量表存放的是基本数据类型
- 局部变量表所需的内存空间再编译期间完成分配
StackOverflowError: 线程请求的栈深度大于虚拟机所允许的深度OutOfMemoryError: 虚拟机栈动态扩展无法申请到足够的内存
3. 本地方法栈(线程私有)
- 运行本地方法
- 其他和 Java 虚拟机栈类似
4. Java 堆(线程共享)
- 在虚拟机启动时创建
- 存放对象实例
- 垃圾回收主要区域
5. 方法区(线程共享)
- 存储已被虚拟机加载的类信息,常量,静态变量,即编译器编译后的代码等数据
- 对常量池的回收和对类型的卸载
其他
运行时常量池
- 运行时常量池是方法区的一部分,
- 类加载后将 Class 文件中的常量池信息放到方法区的运行时常量池中
- String 类的
intern()方法可以把运行期间新的常量放入池中
直接内存
- 直接内存并不是虚拟机运行时数据区的一部分,也不是 Java 虚拟机规范中定义的内存区域
举例
请看下面例子:
public class Test {
public static void main(String args[]) {
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);
String s3 = new String("abc");
System.out.println(s1 == s3);
System.out.println(s1 == s3.intern());
}
}
打印结果为:
true
false
true
解析:
- 第一个 true 是因为 "abc" 为字符串常量,是放在方法区中的,虽然会开启内存但是会统一指向到运行时常量池中的 HashSet,由 HashSet 统一管理,这时 s1, s2 指向的地址自然就是 HashSet,
s1 == s2当然为 true - 第二个为 false 是因为 s3 是一个对象实例,实例是放在 Java 堆中,s1 是放在方法区中,两者地址不一样,所以为 false
- 第三个为 true 是因为 intern() 方法可以把新的常量放入池中,所以为 true
《深入理解 Java 虚拟机》学习笔记 -- 内存区域的更多相关文章
- 深入理解Java虚拟机学习笔记(一)-----Java内存区域
一 概述 对于 Java 程序员来说,在虚拟机自动内存管理机制下,不再需要像C/C++程序开发程序员这样为内一个 new 操作去写对应的 delete/free 操作,不容易出现内存泄漏和内存溢出问题 ...
- 深入理解java虚拟机学习笔记(一)JVM内存模型
上周末搬家后,家里的宽带一直没弄好,跟电信客服反映了N遍了终于约了个师傅明天早上来迁移宽带,可以结束一个多星期没网的痛苦日子了.这段时间也是各种忙,都一个星期没更新博客了,再不写之前那种状态和激情都要 ...
- 深入理解java虚拟机学习笔记(二)垃圾回收策略
上篇文章介绍了JVM内存模型的相关知识,其实还有些内容可以更深入的介绍下,比如运行时常量池的动态插入,直接内存等,后期抽空再完善下上篇博客,今天来介绍下JVM中的一些垃圾回收策略. 一. ...
- 深入理解Java虚拟机学习笔记(二)-----垃圾收集器与内存分配策略
写在前面 本节常见面试题: 如何判断对象是否死亡(两种方法). 简单的介绍一下强引用.软引用.弱引用.虚引用(虚引用与软引用和弱引用的区别.使用软引用能带来的好处). 如何判断一个常量是废弃常量 如何 ...
- 深入理解Java虚拟机 - 学习笔记 1
Java内存区域 程序计数器 (Program Counter Register) 是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里,字节码解释器工作时就是通过 ...
- 深入理解java虚拟机学习笔记(二)
第三章 垃圾收集器与内存分配策略 概述 程序计数器.虚拟机栈.本地方法栈3个区随线程而生,随线程而灭.因此大体上可认为这几个区域的内存分配和回收都具备确定性.在方法/线程结束时,内存自然就跟着回收 ...
- 深入理解java虚拟机学习笔记(一)
第二章 Java内存区域与内存溢出异常 运行时数据区域 程序计数器(Program Counter Register) 程序计数器:当前线程所执行的字节码行号指示器.各条线程之间计数器互不影响,独立存 ...
- 深入理解Java虚拟机学习笔记(三)-----类文件结构/虚拟机类加载机制
第6章 类文件结构 1. 无关性 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(即扩展名为 .class 的文件) 是构成平台无关性的基石. 字节码(即扩展名为 .class 的文 ...
- 类加载机制(深入理解JAVA虚拟机学习笔记)
1.类加载机制的定义 将class文件加载到内存,然后对class文件中的数据进行校验.解析和初始化,转换成可以被虚拟机直接使用的JAVA类型,这就是虚拟机的类加载机制.(在JAVA中,类的加载.连接 ...
随机推荐
- 发布机制-灰度发布-例子:Windows
ylbtech-发布机制-灰度发布-例子:Windows 在传统软件产品发布过程中(例如微软的Windows 7的发布过程中),一般都会经历Pre-Alpha.Alpha.Beta.Release c ...
- Android : 高通平台的HVX简介及调试
一.HVX简介 HVX(“Hexagon矢量扩展”,Hexagon-六边形.Vector-矢量.Extensions-扩展)是Hexagon 680 DSP的典型特性,能够在执行图像处理应用中的计算负 ...
- VBA锁定指定单元格
Then .Range("AF4").Value = pjno .Range("A1:AH56").Locked = False .Range("F6 ...
- Kettle源码学习(一)——把Kettle项目跑起来
kettle(pentaho data integration),是一款开源的C/S版的ETL工具,最近打算学习一下kettle源码,并自己写一个mini kettle,并改造成基于事件触发的流处理模 ...
- python用cx_Oracle连接oracle
确认版本: oracle版本:64位 python版本:64位 下载cx_Oracle的whl包:64位 安装whl包:pip install wheel cd到下载路径安装cx_Oracle的whl ...
- rsync+inotify实时数据同步
没有实际的用过,先mark一下,后面实践. https://www.osyunwei.com/archives/7447.html 一.为什么要用Rsync+sersync架构? 1.sersync是 ...
- Fluent操作流程&&udf编译
Fluent 操作流程 1, 读网格模型 2, Scale修改单位 3, Check检查网格是否符合要求,最小体积不能出现负数 4, Time 选择瞬态,重力设置 5, Models-Multipha ...
- SpringBoot: 6.文件上传(转)
1.编写页面uploadFile.html <!DOCTYPE html> <html lang="en"> <head> <meta c ...
- spring-boot结合maven配置不同环境的profile
1.在spring-boot中新建配置文件 spring-boot不同环境配置文件格式为application-{profile}.yml 说明: 如果application.yml中的配置和appl ...
- Linux详细介绍以及常用命令
Linux系统说明 Linux( 诞生于1991.10.5) 继承了Unix以网络为核心的设计思想, 是一个性能稳定的多用户网络操作系统. Linux这个词严格意义上只表示Linux内核, 但日常中, ...