用Java开发已经四年,中途学了python,Scala,接触这些开发语言后,总感觉Java就像老奶奶裹脚——又臭又长。然,Java虐我千百遍,我待Java如初恋。聊起Java,不得不谈Java的内存结构,请注意,要区别Java内存模型(JMM,关于happens-before、读写屏障啥的)

结构图

java内存结构包括5大部分,先来一张图围观一下:

其中堆存放的有对象实例、数组;局部变量表存储各种基本数据类型,对象引用(区别对象实例,这个是对象在堆中的地址);方法区存储已被虚拟机加载的类信息、常量、静态变量、即使编译器编译后的代码等数据。

what?这些和我学习Java有毛线关系?来,请思考下面这道题中i、j、k的值:

    public static void main(String[] args) {
int i =1;
i =i++;
int j =i++;
int k = i + ++i *i++;
System.out.println("i = "+i);
System.out.println("j = "+j);
System.out.println("k = "+k);
}

我们需要知道,程序的执行就是不断入栈出栈的过程,int i =1,就是在本地变量表中存入i的值1,先来撸张初始状态的图。

i =i++;

这个操作执行了下面的过程:

  • 将i 的值1压入操作数栈;
  • 修改局部变量表中的i值,为2;
  • 赋值语句执行出栈操作,将操作数栈中i的值1返回给局部变量表中的i。

这个操作执行后你会神奇的发现:原来啥子也没有变。

int j =i++;

这个操作执行了下面的过程:

  • 在局部变量表中添加变量j;
  • 将i的值入栈,为1;
  • 修改局部变量表中的i值,为2;
  • 赋值语句将操作数栈中的i出栈,赋值给j,为1;

此时内存中的变量状态如下:

int k = i + ++i *i++;

这个操作执行了下面的过程:

  • 在局部变量表中添加变量k;
  • 将i的值加入操作数栈,为2;
  • 将局部变量表中的i值加1,为3(注意++i和i++执行顺序的区别);
  • 将局部变量表中的i值加入操作数栈,为3(第二个i);
  • 将局部变量表中的i值再次加入操作数栈,为3(第三个i);
  • 将局部变量表中的i值加1,为4;
  • 赋值语句执行出栈操作 3+3+2,将值11赋值给k;

下面的图是没有执行赋值语句前的内存中变量状态:

相信你已经知道最后的结果了吧:

i = 4
j = 1
k = 11

你是不是要感叹下:原来还能这样…

java内存结构学习的一种打开方式的更多相关文章

  1. Java 内存结构备忘录

    本文详细描述了 Java 堆内存模型,垃圾回收算法以及处理内存泄露的最佳方案,并辅之以图表,希望能对理解 Java 内存结构有所帮助.原文作者 Sumith Puri,本文系 OneAPM 工程师编译 ...

  2. Java内存结构详解

    Java内存结构详解 Java把内存分成:栈内存,堆内存,方法区,本地方法区和寄存器等. 下面分别介绍栈内存,堆内存,方法区各自一些特性: 1.栈内存 (1)一些基本类型的变量和对象的引用变量都是在函 ...

  3. Java内存结构、类的初始化、及对象构造过程

    概述 网上关于该题目的文章已经很多,我觉得把它们几个关联起来讲可能更好理解一下.与其它语言一样,它在执行我们写的程序前要先分配内存空间,以便于存放代码.数据:程序的执行过程其实依然是代码的执行及数据的 ...

  4. Java连接Oracle数据库的三种连接方式

    背景: 这两天在学习Oracle数据库,这里就总结下自己上课所学的知识,同时记录下来,方便整理当天所学下的知识,也同时方便日后自己查询. SQL语句的话,这里我就不多讲了,感觉和其他的数据库(MySQ ...

  5. 文件的三种打开方式及with管理文件上下文

    文件的三种打开方式及with管理文件上下文 一.文件的三种打开方式 1.1 只读 f = open(r'D:\pycharm\yjy\上海python学习\456.txt','r',encoding= ...

  6. Java使用SFTP和FTP两种连接方式实现对服务器的上传下载 【我改】

    []如何区分是需要使用SFTP还是FTP? []我觉得: 1.看是否已知私钥. SFTP 和 FTP 最主要的区别就是 SFTP 有私钥,也就是在创建连接对象时,SFTP 除了用户名和密码外还需要知道 ...

  7. <<深入Java虚拟机>>-第二章-Java内存区域-学习笔记

    Java运行时内存区域 Java虚拟机在运行Java程序的时候会将它所管理的内存区域划分为多个不同的区域.每个区域都有自己的用途,创建以及销毁的时间.有的随着虚拟机的启动而存在,有的则是依赖用户线程来 ...

  8. JVM运行时内存结构学习

    学习JVM运行模型比较重要,先看一幅图片: 运行时数据区(内存结构) :  1.方法区(Method Area)类的所有字段和方法字节码,以及一些特殊方法如构造函数,接口代码也在这里定义.简单来说,所 ...

  9. Java 内存模型学习笔记

    1.Java类 public class Math { public static final Integer CONSTANT = 666; public int math(){ int a = 1 ...

随机推荐

  1. C#项目 学生选课系统 C#窗口 Winform项目 项目源码及使用说明

    这是一个学生选课信息管理系统,使用VS2010+SQL2008编写,VS2017正常使用. 项目源码下载地址 https://gitee.com/whuanle/xkgl 笔者录了两个视频,打开项目源 ...

  2. .net图表之ECharts随笔05-不同01的语法步骤

    找了好久,一直没找到可用的热力图heatmap.js. 应该说,使用01中的语法一直都无法实现热力图.只能说我太菜了... 现在急于求成,我找了另一种语法来调用ECharts.此种语法的js文件集是从 ...

  3. jzoj3084

    發現題目函數本質是: 1.將某一數x的末尾1去掉 2.不斷將這個數/2,直到遇到新的1 我們發現一個數z可以用y步到達數x,記x二進制長度為c,分2種情況討論: 1.x是奇數,則z的前c個二進制數必須 ...

  4. 【Spark调优】:RDD持久化策略

    [场景] Spark对RDD执行一系列算子操作时,都会重新从头到尾计算一遍.如果中间结果RDD后续需要被被调用多次,可以显式调用 cache()和 persist(),以告知 Spark,临时保存之前 ...

  5. 简单理解jQuery中$.getJSON、$.get、$.post、$.ajax用法

    在WEB开发中异步请求方式普遍使用,ajax技术减少程序员的工作量,也提升用户交互体验.AJAX的四种异步请求方式都能实现基本需求,闲话不多说,直接切入正题. 1.$.getJSON $.getJSO ...

  6. Windows + VS2013 + Dlib

    Dlib是一个机器学习的C++库,包含了许多机器学习常用的算法, 而且文档和例子都非常详细. 安装有点类似于opencv,这里我从官网下载dlib-18.17到D盘 1. cmake转VS工程 这里使 ...

  7. iOS-xcconfig环境变量那些事(配置环境的配置)

    前言 在配置宏定义参数时,会发现一个问题,在需要临时修改或者测试一些数据时,修改宏,如果不修改,就多写一个,注释掉原来的,然后测试后,再换回来,当然了,如果一两个宏,可以这样,但是,如果每次改的比较多 ...

  8. 在Ubuntu下编译安装nginx

    一.安装nginx 1.安装前提 a)epoll,linux内核版本为2.6或者以上 b)gcc编译器,g++编译器 c)pcre库,函数库,支持解析正则表达式 d)zlib库:压缩解压功能 e)op ...

  9. HTTP响应状态码 含义

    100 客户端可以继续 101 指示服务器正根据 Upgrade 头切换协议 200 请求正常成功 201 指示请求成功并在服务器上创建了一个新资源 202 指示已接受请求进行处理但处理尚未完成 20 ...

  10. Python:高效计算大文件中的最长行的长度

    在操作某个很多进程都要频繁用到的大文件的时候,应该尽早释放文件资源(f.close()) 前2种方法主要用到了列表解析,性能稍差,而最后一种使用的时候生成器表达式,相比列表解析,更省内存 列表解析和生 ...