java虚拟机内存区域介绍


本文将简单介绍下java内存区域,借此加深对java虚拟机的理解;
希望对入门者有一定的引导作用,同时也作为记录帮助自己记忆,若有错误,希望大牛指点一二;

简述

java虚拟机所管理的内存包括这几个运行时数据区:程序计数器、java虚拟机栈、本地方法栈、java堆、方法区、直接内存;
参考图片(来自《深入理解java虚拟机》,推荐阅读):
java虚拟机运行时数据区

程序计数器

  • 当前线程所执行的字节码的行号指示器,根据这里的值来选取下一条需要执行的字节码指令;
  • 每个线程都有一个程序计数器,各线程互不影响;

java虚拟机栈

  • 线程私有的,线程间互不干扰,生命周期与线程相同;
  • 描述java方法执行的内存模型,每个方法再执行时会建立一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息;每个方法调用至完成就对应一个栈帧(栈帧是方法运行时的基础数据结构)再虚拟机栈中入栈到出栈的过程;
  • 其中局部变量表存放了编译器可知的各种基本数据类型;
  • 这个区域存在两种异常状况:StackOverflowError(线程请求的栈深度大于虚拟机允许深度)和OutOfMemoryError(扩展时无法申请足够内存);

本地方法栈

  • 与虚拟机栈作用相似, 为虚拟机使用的Native方法服务;
  • 也会抛出StackOverflowError和OutOfMemoryError;

java堆

  • java虚拟机管理内存中最大的一块, 是所有线程共享的一块内存区域;
  • 用来存放对象实例;
  • 是垃圾收集器管理的主要区域,又称为”GC堆”;
  • 可分为新生代和老年代,再细分为Eden空间 From Survivor和To Survivor空间 ;
  • 堆无法扩展时会抛出OutOfMemoryError异常;

方法区

  • 各个线程共享的内存区域;
  • 存储虚拟机加载的类信息、常量、静态变量、编译后的代码等;
  • 内存不满足时抛出OutOfMemoryError异常;

直接内存

  • 内存不够会抛出OutOfMemoryError异常;
  • 不是虚拟机运行时数据区的一部分;

对象创建

  • 虚拟机遇到new指令,检查参数是否能在常量池中定位到类的符号引用,若没有,先执行类加载过程(该过程会在后续文章进行分享);
  • 类加载检查完,在java堆中为对象分配内存(受不同收集器影响);
  • 虚拟机对对象进行一些设置:是哪个类的实例,如何查找类元数据信息,对象哈希码,对象的GC分代年龄等;
  • 执行init进行初始化;

对象的访问定位

  • 需要通过栈上的reference数据来操作栈上的对象;
  • 两种访问方式:
    • 句柄:java堆种一块内存作为句柄池,reference保存对象的句柄地址,句柄再保存对象实例数据和类型数据的具体地址信息;
    • 直接指针:java堆对象放置访问类型数据,reference种存储对象地址;

以上是对java虚拟机涉及内存以及对象创建、对象访问定位流程的简单介绍,后续会继续进行相关基础和进阶知识的学习整理分享,欢迎一起讨论交流~


文章作者: Xudong Jiang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Xudong Jiang !
 上一篇
elasticsearch升级-transportClient转HighLevelRestClient elasticsearch升级-transportClient转HighLevelRestClient
今天分享下项目中进行elasticsearch升级,同时伴随着transport Client转换位High Level Rest Client. 升级迁移步骤 es 集群升级(DBA操作) 数据全量迁移 使用High Level Rest
2020-01-02
下一篇 
java并发专题-线程池介绍 java并发专题-线程池介绍
今天介绍下java中的线程池应用,主要介绍java中的Excutor框架 线程池的好处 提高响应速度,处理任务时无需等待线程创建; 提高线程管理性,对线程池内线程统一分配、调度、管理; 降低资源消耗,通过重复利用已创建的线程降低线程创建和销
2019-12-08
  目录