首先,内存模型图,如下:

其次,一句话概括各个区域的作用:

1:程序计数器(Program Counter Register),让虚拟机中的字节码解释器通过改变计数器的值来获取下一条代码指令,比如分支、循环、跳转、异常处理、线程恢复等;

2:Java 虚拟机栈(Java Virtual Machine Stacks),栈顶存放当前方法,里面有局部变量表,

3:本地方法栈(Native Method Stacks),本地方法栈则,是为虚拟机使用到的Native 方法服务,作用同虚拟机栈。

4:Java 堆(Java Heap)是Java 虚拟机所管理的内存中最大的一块,是被所有线程共享的一块内存区域。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

5:方法区(Method Area)与Java 堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

一:创建一个引用类型对象的内存图

Object obj = new Object();

假设这句代码出现在方法体中,那:

1:首先包含这个方法体的类首先被加载到方法区中;

2:其次方法体本身被压栈进虚拟机栈;

3:“Object obj”这部分的语义将会反映到虚拟机栈的本地变量表中,作为一个reference 类型数据出现。

4:而“new Object()”这部分的语义将会反映到Java 堆中,形成一块存储了Object 类型所有实例数据值(Instance Data,对象中各个实例字段的数据)的结构化内存,这块内存的地址存储在虚拟机栈。另外,在Java 堆中还必须包含能查找到此对象类型数据(如对象类型、父类、实现的接口、方法等)的地址信息,这些类型数据则存储在方法区中。

以上过程,用一个更具体的例子,就是创建数组,其内存图如下:

二:创建二位数组的内存图

如下,为了简单起见,省略了方法区的描述:

三:方法调用内存图

假设是这样一段代码,

public class MethodInvoker {
    public static void main(String[] args) {
        int re = add(1,2);
        System.out.println(re);
    }

private static int add(int i, int j) {
        return i + j;
    }
}

其内存图是如下的,

准备动作是类和方法的信息加载到方法区,接下来,

1:main方法压栈;

2:方法执行过程中add方法压栈,然后方法执行,返回3;

3:add方法被弹栈,main方法打印3;

4:main方法弹栈;

三:自定义引用类型对象创建内存图

第一步:

第二步:

附件:关于虚拟机栈访问堆中的数据,有两种方式,如下:

由于reference 类型在Java 虚拟机规范里面只规定了一个指向对象的引用,并没有定义这个引用应该通过哪种方式去定位,以及访问到Java 堆中的对象的具体位置,因此不同虚拟机实现的对象访问方式会有所不同,主流的访问方式有两种:使用句柄和直接指针。

如果使用句柄访问方式,Java 堆中将会划分出一块内存来作为句柄池,reference中存储的就是对象的句柄地址,而句柄中包含了对象实例数据和类型数据各自的具体地址信息,如下图所示。

如果使用直接指针访问方式,Java 堆对象的布局中就必须考虑如何放置访问类型数据的相关信息,reference 中直接存储的就是对象地址,如下图所示

各个JAVA场景下的内存图的更多相关文章

  1. 13.Java基础_数组内存图

    单个数组内存图 new int[3]: 在堆内存里申请一块空间存储int类型的变量(初始化时值都为0) int[] array: 在栈内存申请一块内存存储堆内存里数组的首地址 array[i]: 通过 ...

  2. Java中创建对象的内存图

    所有人都知道面向对象思想,Java中的对象的创建在内存中是如何创建的,传智播客的视频看了一遍,把一些讲解的比较清晰的内容记录下来,方便记忆的更加深刻,Java中创建对象的过程,首先要理解JVM中栈.堆 ...

  3. 16.Java基础_对象内存图

    单个对象 1.进入main函数,生成main函数的栈空间 2.先在mian函数的栈空间里产生一个Student变量(以后会用来存储Studnet对象的首地址),然后进入Student类,在堆内存创建S ...

  4. java两个数组内存图

  5. java一个数组的内存图

  6. Java使用极小的内存完成对超大数据的去重计数,用于实时计算中统计UV

    Java使用极小的内存完成对超大数据的去重计数,用于实时计算中统计UV – lxw的大数据田地 http://lxw1234.com/archives/2015/09/516.htm Java使用极小 ...

  7. Linux下用火焰图进行性能分析【转】

    转自:https://blog.csdn.net/gatieme/article/details/78885908 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原 ...

  8. 06-03 Java 面向对象思想概述、开发设计特征,类和对象的定义使用,对象内存图

    面向对象思想概述.开发设计特征 1:面向对象思想 面向对象是基于面向过程的编程思想. 面向过程:强调的是每一个功能的步骤 面向对象:强调的是对象,然后由对象去调用功能 2:面向对象的思想特点 A:是一 ...

  9. 【JAVA】笔记(1)---JVM内存图;方法重载条件;输入方法;转义字符;强制类型转换;变量分类及区别;Java命名规范;

    Java命名规范: 1.包:全部字母小写: 2.类+接口:所有单词的首字母大写: 3.变量+方法:第一个单词的首字母小写,其余单词首字母大写: 3.常量名:所有字母均大写,且用下划线" _ ...

随机推荐

  1. 【PAT】1043 Is It a Binary Search Tree(25 分)

    1043 Is It a Binary Search Tree(25 分) A Binary Search Tree (BST) is recursively defined as a binary ...

  2. 【LOJ】#2111. 「JLOI2015」战争调度

    题解 记录一个数组dp[i][S][k]表示第i个点,它上面所有的点的状态(参军或者后勤)可以用状态S来表示,一共有k个平民参军的最大收益,当然数组开不下,可以用vector动态开 我们对于每个平民枚 ...

  3. 应用Mongoose开发MongoDB(1)数据库连接

    最近因为项目,接触了MongoDB,因为是分工合作,我负责的部分主要是实现前端对数据库增删查改的需求,因此以下内容只着重于针对不同问题如何进行解决. 整个工程的最终目的是通过mongoose编写数据库 ...

  4. R语言编程艺术(5)R语言编程进阶

    本文对应<R语言编程艺术> 第14章:性能提升:速度和内存: 第15章:R与其他语言的接口: 第16章:R语言并行计算 ================================== ...

  5. 003.KVM虚拟机部署-CentOS6.8

    一 实验说明 CentOS 7的KVM虚拟机推荐使用qcow2磁盘格式,本实验在KVM中安装CentOS 6.8 64虚拟机. 二 命令部署过程 2.1 上传镜像 使用winscp上传至/data/i ...

  6. 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考

    2018年12月12日18:44:53 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考 案件现场 不久前,在开发改造公司一个端到端监控日志系统的时候,出现了一 ...

  7. linux学习笔记-11.正则表达式

    1.cut截取以:分割保留第七段 grep hadoop /etc/passwd | cut -d: -f7 2.排序 du | sort -n 3.查询不包含hadoop的 grep -v hado ...

  8. poj-1459-最大流dinic+链式前向星-isap+bfs+stack

    title: poj-1459-最大流dinic+链式前向星-isap+bfs+stack date: 2018-11-22 20:57:54 tags: acm 刷题 categories: ACM ...

  9. 【python学习-2】python起步必备

    1.python缩进 python 缩进是tab,还是空格呢?都可以,可以是一个tab,也可以是4个空格,但是最重要的是整个python脚本的缩进必须统一,否则会报错. 2.代码注释 python注释 ...

  10. web前端面试经历分享

    十天前,我还在纠结这个暑假到底是呆在实验室研究技术好还是找一份实习见识世面好,而现在我已经接到offer准备工作了.这几天真是累得够呛,一方面需要拼命准备期末考试,另一方面,需要往公司里面跑接受面试. ...