《深入理解 Java 虚拟机》学习笔记 -- 内存区域

运行时数据区域

主要分为 6 部分:

  1. 程序计数器
  2. 虚拟机栈
  3. 本地方法栈
  4. Java 堆
  5. 方法区

如图所示:

1. 程序计数器(线程私有)
  1. 程序计数器是当前线程所执行字节码的行号指示器
  2. 字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令
  3. 为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器
  4. 执行 Java 方法,计数器记录的是正在执行的虚拟机字节码指令的地址;执行的是 Native 方法,计数器为空
  5. 程序计数器是唯一一个在 Java 虚拟机中不会出现 OutOfMemoryError 情况的区域
2. Java 虚拟机栈(线程私有)
  1. 每个方法被执行的时候都会同时创建一个栈帧
  2. 每一个方法被调用直至执行完成的过程,就对应者一个栈帧再虚拟机中从入栈到出战的过程
  3. ”栈内存“指的就是虚拟机栈中的局部变量表部分
  4. 局部变量表存放的是基本数据类型
  5. 局部变量表所需的内存空间再编译期间完成分配
  6. StackOverflowError : 线程请求的栈深度大于虚拟机所允许的深度
  7. OutOfMemoryError: 虚拟机栈动态扩展无法申请到足够的内存
3. 本地方法栈(线程私有)
  1. 运行本地方法
  2. 其他和 Java 虚拟机栈类似
4. Java 堆(线程共享)
  1. 在虚拟机启动时创建
  2. 存放对象实例
  3. 垃圾回收主要区域
5. 方法区(线程共享)
  1. 存储已被虚拟机加载的类信息,常量,静态变量,即编译器编译后的代码等数据
  2. 对常量池的回收和对类型的卸载

其他

运行时常量池
  1. 运行时常量池是方法区的一部分,
  2. 类加载后将 Class 文件中的常量池信息放到方法区的运行时常量池中
  3. String 类的 intern() 方法可以把运行期间新的常量放入池中
直接内存
  1. 直接内存并不是虚拟机运行时数据区的一部分,也不是 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

解析:

  1. 第一个 true 是因为 "abc" 为字符串常量,是放在方法区中的,虽然会开启内存但是会统一指向到运行时常量池中的 HashSet,由 HashSet 统一管理,这时 s1, s2 指向的地址自然就是 HashSet,s1 == s2 当然为 true
  2. 第二个为 false 是因为 s3 是一个对象实例,实例是放在 Java 堆中,s1 是放在方法区中,两者地址不一样,所以为 false
  3. 第三个为 true 是因为 intern() 方法可以把新的常量放入池中,所以为 true

《深入理解 Java 虚拟机》学习笔记 -- 内存区域的更多相关文章

  1. 深入理解Java虚拟机学习笔记(一)-----Java内存区域

    一 概述 对于 Java 程序员来说,在虚拟机自动内存管理机制下,不再需要像C/C++程序开发程序员这样为内一个 new 操作去写对应的 delete/free 操作,不容易出现内存泄漏和内存溢出问题 ...

  2. 深入理解java虚拟机学习笔记(一)JVM内存模型

    上周末搬家后,家里的宽带一直没弄好,跟电信客服反映了N遍了终于约了个师傅明天早上来迁移宽带,可以结束一个多星期没网的痛苦日子了.这段时间也是各种忙,都一个星期没更新博客了,再不写之前那种状态和激情都要 ...

  3. 深入理解java虚拟机学习笔记(二)垃圾回收策略

    上篇文章介绍了JVM内存模型的相关知识,其实还有些内容可以更深入的介绍下,比如运行时常量池的动态插入,直接内存等,后期抽空再完善下上篇博客,今天来介绍下JVM中的一些垃圾回收策略.        一. ...

  4. 深入理解Java虚拟机学习笔记(二)-----垃圾收集器与内存分配策略

    写在前面 本节常见面试题: 如何判断对象是否死亡(两种方法). 简单的介绍一下强引用.软引用.弱引用.虚引用(虚引用与软引用和弱引用的区别.使用软引用能带来的好处). 如何判断一个常量是废弃常量 如何 ...

  5. 深入理解Java虚拟机 - 学习笔记 1

    Java内存区域 程序计数器 (Program Counter Register) 是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里,字节码解释器工作时就是通过 ...

  6. 深入理解java虚拟机学习笔记(二)

    第三章 垃圾收集器与内存分配策略 概述 ​ 程序计数器.虚拟机栈.本地方法栈3个区随线程而生,随线程而灭.因此大体上可认为这几个区域的内存分配和回收都具备确定性.在方法/线程结束时,内存自然就跟着回收 ...

  7. 深入理解java虚拟机学习笔记(一)

    第二章 Java内存区域与内存溢出异常 运行时数据区域 程序计数器(Program Counter Register) 程序计数器:当前线程所执行的字节码行号指示器.各条线程之间计数器互不影响,独立存 ...

  8. 深入理解Java虚拟机学习笔记(三)-----类文件结构/虚拟机类加载机制

    第6章 类文件结构 1. 无关性 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(即扩展名为 .class 的文件) 是构成平台无关性的基石. 字节码(即扩展名为 .class 的文 ...

  9. 类加载机制(深入理解JAVA虚拟机学习笔记)

    1.类加载机制的定义 将class文件加载到内存,然后对class文件中的数据进行校验.解析和初始化,转换成可以被虚拟机直接使用的JAVA类型,这就是虚拟机的类加载机制.(在JAVA中,类的加载.连接 ...

随机推荐

  1. scarpy crawl 爬取微信小程序文章

    import scrapy from scrapy.linkextractors import LinkExtractor from scrapy.spiders import CrawlSpider ...

  2. Leetcode题目79.单词搜索(回溯+DFS-中等)

    题目描述: 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格.同一个单元格内的字母不允许 ...

  3. MySQL-UDF和MOF提权

    MOF提权 MOF文件是mysql数据库的扩展文件(在c:/windows/system32/wbem/mof/nullevt.mof) 叫做”托管对象格式”,其作用是每隔五秒就会去监控进程创建和死亡 ...

  4. 通过Maven更换环境配置文件

    大致思路:配置文件有三套:main/resources.devmain/resources.prodmain/resources.test公共部分放到main/resource下使用mvn clean ...

  5. 10分钟梳理MySQL核心知识点

    数据库的使用,是开发人员的基本功,对它掌握越清晰越深入,你能做的事情就越多. 做业务,要懂基本的SQL语句:做性能优化,要懂索引,懂引擎:做分库分表,要懂主从,懂读写分离... 今天我们用10分钟,重 ...

  6. requests和BeautifulSoup模块的使用

    用python写爬虫时,有两个很好用第三方模块requests库和beautifulsoup库,简单学习了下模块用法: 1,requests模块 Python标准库中提供了:urllib.urllib ...

  7. 对于ssh服务的简单配置,似的自己的服务器更加安全

    对于一台服务器,最大的问题莫过于安全.没有安全性的服务器即使再牛*,性能再好,作用再大,也是分分钟被人搞定,而且还是揉虐性的...当然万事没有绝对的安全,我们只是将危险降低而已.本文只针对于ssh服务 ...

  8. .netcore多语言解决方案

    这里本文使用Microsoft.AspNetCore.Localization来实现多语言的解决方案 默认是包含这个包的,所有不需要再额外安装 首先需要注入我们需要的服务 1.在startup.cs中 ...

  9. C语言中函数strcpy ,strncpy ,strlcpy的用法

    strcpy ,strncpy ,strlcpy的用法 好多人已经知道利用strncpy替代strcpy来防止缓冲区越界. 但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式. 1. s ...

  10. 深度学习之NLP获取词向量

    1.代码 def clean_text(text, remove_stopwords=False): """ 数据清洗 """ text = ...