《深入理解 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中,类的加载.连接 ...
随机推荐
- Spring AOP常见面试题
一.AOP是什么? 与OOP对比,面向切面,传统的OOP开发中的代码逻辑是至上而下的过程中会长生一些横切性问题,这些横切性的问题和我们的主业务逻辑关系不会散落在代码的各个地方,造成难以维护,AOP的编 ...
- QAbstractTableModel中的data()到底执行几遍???
发现问题的过程 1.一个普通的继承 QAbstractTableModel 的类 class CurrencyModel : public QAbstractTableModel { public: ...
- HearthBuddy 日志模块
// Triton.Common.LogUtilities.CustomLogger // Token: 0x04000BD8 RID: 3032 private Level level_0 = Le ...
- 【SR汇总】基于深度学习方法
1.SRCNN.FSRCNN (Learning a Deep Convolutional Network for Image Super-Resolution, ECCV2014) (Acceler ...
- Handler注意事项
一. Handler与Thread的区别. Handler与调用者处于同一线程,如果Handler里面做耗时的动作,调用者线程会阻塞.Android UI操作不是线程安全的,并且这些操作必须在UI线程 ...
- 深度学习之DCGAN
1.知识点 """ DCGAN:相比GAN而言,使用了卷积网络替代全连接 卷积:256*256*3 --- > 28*28*14 -->结果 ,即H,W变小, ...
- Python类call函数的作用
call函数可以把类变成函数来调用call方法 class Demo(): def __init__(self, name): self.name = name def __call__(self): ...
- 部署Hadoop-3.0-高性能集群
一.Hadoop概述: Hadoop是一个由Apache基金会所开发的分布式系统基础架构.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力进行高速运算和存储.Hadoop的框 ...
- Docker Windows
docker windows 操作和linux上稍有些差异,主要是在启动容器时的命令参数 和 端口映射. 1.下载docker-toolbox http://mirrors.aliyun.com/do ...
- python实现迭代法求方程组的根
有方程组如下: 迭代法求解x,python代码如下: import numpy as np import matplotlib.pyplot as plt A = np.array([[8, -3, ...