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

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

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. maven正确的集成命令-U -B 等

    在持续集成服务器上使用怎样的 mvn 命令集成项目,这个问题乍一看答案很显然,不就是 mvn clean install 么?事实上比较好的集成命令会稍微复杂些,下面是一些总结: 不要忘了clean: ...

  2. 【LOJ】#2508. 「AHOI / HNOI2018」游戏

    题解 把没有门的点缩成一个点 如果\(i->i + 1\)的钥匙大于\(i\),那么\(i\)不可以到\(i + 1\),连一条\(i\)到\(i + 1\)的边 如果\(i->i + 1 ...

  3. js加入购物车抛物线动画

    天猫将商品加入购物车会有一个抛物线动画,告诉用户操作成功以及购物车的位置,业务中需要用到类似的效果,记录一下实现过程备忘,先上demo 一开始没有想到用抛物线函数去做,也已经忘记还有这么个函数了,想着 ...

  4. ViewPager 无限循环

    Overview 我们在使用ViewPager来制作图片轮播的时候,常常为ViewPager不能一直无限循环的问题所苦恼.对于这个问题,目前从网上找到了两个思路来解决: 将 ViewPager 的Co ...

  5. Xamarin iOS教程之添加和定制视图

    Xamarin iOS教程之添加和定制视图 Xamarin iOS用户界面——视图 在iPhone或者iPad中,用户看到的摸到的都是视图.视图是用户界面的重要组成元素.例如,想要让用户实现文本输入时 ...

  6. BZOJ.3680.吊打XXX(模拟退火/爬山算法)

    题目链接 一个比较好的解释? 模拟退火(Simulated Annealing,SA): (1)初始化一个温度(充分大).初始解状态S.每个T值的迭代次数. (2)对i=1,...,L,做(3)至(7 ...

  7. Nginx增加模块

    http://blog.csdn.net/loyachen/article/details/50902667

  8. 使用 IntraWeb (23) - 基本控件之 TIWTimer、TIWProgressBar、TIWProgressIndicator、TIWTimeEdit

    TIWTimer //和 TTimer 没多大区别, 它的默认事件现在是异步的(OnAsyncTimer), 在网络上使用 OnTimer 肯定是非常糟糕的 TIWProgressBar //进度条 ...

  9. CentOS下KVM配置NAT网络(网络地址转换模式)

    KVM虚拟机Nat方式上网: # 查看当前活跃的网络 virsh net-list # 查看该网络的详细配置 virsh net-dumpxml default 客户机的XML配置文件中interfa ...

  10. LPC43xx双核笔记

    简介本页提供了一些使用LPC43xx器件双核特性的基本信息.此页面上的信息和专题使用Keil uVision4工具,以双核工程的使用来演示.该工程初始化两个内核以运行FreeRTOS,并采用三色LED ...