《深入理解 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中,类的加载.连接 ...
随机推荐
- Flutter移动电商实战 --(12)首页导航区域编写
1.导航单元素的编写 从外部看,导航是一个GridView部件,但是每一个导航又是一个上下关系的Column.小伙伴们都知道Flutter有多层嵌套的问题,如果我们都写在一个组件里,那势必造成嵌套严重 ...
- ora-01578
SQL> exec DBMS_STATS.GATHER_DATABASE_STATS; BEGIN DBMS_STATS.GATHER_DATABASE_STATS; END; * ERROR ...
- VC++实现标准型计算器步骤及源码
VC++实现标准型计算器步骤及源码 2013年06月19日 09:48:47 无敌的成长日记 阅读数:4686 最近一段时间一直在做这个东西,刚刚拿到题目的时候认为这是一个简单的程序,可是 ...
- Android : 供应商原生开发套件 (VNDK)
一.VNDK概述 VNDK(Vendor Native Development Kit)是一组专门用于vendor实现其HAL的lib库,因为自Android 8.0以来,Google引入了Trebl ...
- hibernate关联映射之一对多&多对一
package loaderman.b_one2Many; import java.util.HashSet; import java.util.Set; public class Dept { pr ...
- UiUtils
import android.app.Activity; import android.app.Dialog; import android.content.Context; import andro ...
- JVM学习笔记之JDK、JRE、JVM的关系(二)
JDK(Java Development Kit)是针对Java开发员的产品,是整个Java的核心,包括了Java运行环境JRE.Java工具和Java基础类库.Java Runtime Enviro ...
- js图片预览带进度条
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- syspolicy_purge_history作业故障排除
描述 我们有一台数据库服务器windows 2012 r2 上有安装sql server 2012 和sql server 2016双实例,后续又把sql 2016的服务全部停用,即只保留sql 20 ...
- Mybatis高级结果映射
有时侯,我们用SQL取得的结果需要映射到类似Map<key, Bean>这样的数据结构中或是映射到多个实体类中时,我们就需要使用到resultMap.下面用3个例子说明Mybatis高级结 ...