菜鸟学Java(二十三)——Java内存分析
我们常说的Java内存主要分为四大块(寄存器不在考虑之内,我们无法用代码来操控它):stack(栈)、heap(堆)、data segment(数据区)、code segment(代码区)。它们的主要用途如下图所示:
而在上面四个当中,我们经常谈论的是右边那两个家伙——stack和heap。今天我们就来聊聊Java代码在运行的过程中,在stack和heap中到底是什么样子的吧。
我们先看下面一段代码:
public static void main(String[] args) {
TestReference testReference = new TestReference();
int age = 1;
Person xiaoqiang = new Person("小强", 21);
Person xiaoming = new Person("小明", 22); testReference.selfPlus(age);
System.out.println("age经过selfPlus方法的处理后为:" + age); testReference.changeName(xiaoqiang);
System.out.println("小强经过changeName方法的处理后的名字为:" + xiaoqiang.getName()); testReference.changeAge(xiaoming);
System.out.println("小明经过changeAge方法的处理后的年龄为:" + xiaoming.getAge()); } public void selfPlus(int i) {
i = i + 1;
} public void changeName(Person person) {
person = new Person("小刚");
} public void changeAge(Person person) {
person.setAge(25);
}
执行完以上代码,会打印出什么内容呢?如果你Java基础还可以,那么很容易就能知道会输出什么内容,想要知道以上代码会打印什么内容,需要你明白Java代码在stack和heap中是怎么工作的。下面我们结合几张图来看看:
int i = 1;
Person xiaoqiang = new Person("小强", 21);
Person xiaoming = new Person("小明", 22);
当我们执行完上面三行代码时,内存中的情况如下图所示:
我们知道stack是用来存放变量的,所以age、xiaoqiang和xiaoming三个变量会被存放到stack里,而age又是int类型,所以它的值也会被存放在stack里面。xiaoqiang和xiaoming为Person类型的引用变量,所以stack只会存放它们的一个引用,也就是对应对象的内存地址,而它们真正的内容被存放在了heap里面。
当执行到testReference.selfPlus(i);时,selfPlus(int i)方法被调用,此时会在stack中为形参I开辟一块内存空间,并将其值设置为1,此时内存中的情况如下:
因为调用selfPlus(int i)方法时,将age作为形参传递给该方法,相当于将age的值复制一份给i,所以现在i的值为1,接着执行i = i + 1;此时i的值被修改为2,如图:
此时被修改的只是age的副本,而并非age本身,所以age仍为1,当selfPlus(int i)方法被执行完,i被销毁,age不变。接下来看xiaoqiang,当调用changeName(Person person)方法时,会在stack中为person分配一块空间,里面存放的是xiaoqiang指向的地址,如图:
然后执行到person = new Person("小刚");时,由于又new了一个Person对象,所以在堆中会新建一个person,姓名叫小刚,并且会将person执行小刚的地址,如图:
此时,person指向的对象由小强变成了小刚,但是xiaoqiang所指向的对象仍然是小强,并没有发生任何变化。当changeName方法执行完以后,person被销毁,而小刚也会因为没有任何对象对其进行引用,随后被垃圾回收器回收掉。
下面到了最后一个方法了,当执行testReference.changeAge(xiaoming);时,调用changeAge(Person person)方法,同样会在stack中为person分配一块空间,这次里面存放的是xiaoming对应的内存地址,如图:
然后执行person.setAge(25);,此时person指向的对象为小明,所以在执行setAge方法时,修改的就是heap中小明的属性值,此时小明的年龄被修改为25,。方法执行完毕,person被销毁,内存中最终结果如下:
内存中的最终情况就如上图所示,当然当main方法执行完以后,之前创建的所有对象都会被销毁。OK,每天上班做项目的你是不是把一些基础的东西忘了呢?如果是的话就赶快来补一补吧,好处还是很多的。
菜鸟学Java(二十三)——Java内存分析的更多相关文章
- Java运行原理及内存分析
Java运行原理及内存分析 一.Java运行原理 二.Java内存分析
- Eclipse中的快捷键快速生成常用代码(例如无参、带参构造,set、get方法),以及Java中重要的内存分析(栈、堆、方法区、常量池)
(一)Eclipse中的快捷键: ctrl+shift+f自动整理选择的java代码 alt+/ 生成无参构造器或者提升信息 alt+shift+s+o 生成带参构造 ctrl+shift+o快速导 ...
- Java面向对象_对象内存分析—值传递和引用传递
对象内存分析,我一直学的比较模糊,今天抽空整理一下,希望能理清. 先说一下,内存分析从何而来,这对于我们这些刚接触java的人来说都比较模糊,就从new关键字说起吧. new关键字表示创建一个对象或者 ...
- 巩固java(二)----JVM堆内存结构及垃圾回收机制
前言: 我们在运行程序时,有时会碰到内存溢出(OutOfMemoryError)的问题,为了解决这种问题,我们有必要了解JVM的内存结构和垃圾回收机制. 正文: 1.JVM堆内存结构 ...
- Java数组(基本+内存分析)
一.数组概念 数组即为多个相同数据类型数据的数据按一定顺序排列的集合. 二.数组的特点 1.数组有数组名.索引.元素.素组长度: 2.数组的元素可以是基本数据类型也可以是引用数据类型: ...
- Java的引用类型的内存分析
一. jdk的内存:jdk的bin目录常见命令 1. javac.exe:编译java源代码的,生成java字节码文件(*.class) 2. java.exe:启动一个jvm,来运行指定class字 ...
- java基础知识回顾之---java String final类 容易混淆的java String常量池内存分析
/** * 栈(Stack) :存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放 在常量池中). 堆(heap):存 ...
- Java基础学习笔记二十三 Java核心语法之反射
类加载器 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,链接,初始化三步来实现对这个类进行初始化. 加载就是指将class文件读入内存,并为之创建一个Class对象.任 ...
- java构造器级简单内存分析
java构造器的使用(基础篇) 构造方法也叫构造器,是创建对象时执行的特殊方法,一般用于初始化新对象的属性. 基本定义语法: 访问控制符 构造方法名([参数列表]){ 方法体 } 注:"访问 ...
- Java进阶(二十三)java中long类型转换为int类型
java中long类型转换为int类型 由int类型转换为long类型是向上转换,可以直接进行隐式转换,但由long类型转换为int类型是向下转换,可能会出现数据溢出情况: 主要以下几种转换方法,供参 ...
随机推荐
- Storm消息可靠机制
一:介绍 1.介绍 默认情况是,Spout每获取一条数据,封装后发送给后面的组件,不再管后面是否处理完成或成功接收,不再考虑. 这种的情况是不用太精确,没有启用可靠性消息机制. 2.方面的体现 spo ...
- 一种使用pyinstaller时图标问题解决方案
一种使用pyinstaller时图标问题解决方案 0x00 场景 使用pyinstaller将.py文件编译成.exe文件时,想要使用自己心仪的图标(.ico)比较麻烦.在使用pyinstalle ...
- 在python3下使用requests,xpath,urllib爬取不得姐网站相关视频爬虫源代码
#coding=utf-8 from lxml import etreeimport requestsimport urllibimport os # 获取url的html等内容def getHtml ...
- 洛谷 P1474 货币系统 Money Systems(经典)【完全背包】+【恰好装满的最大方案数量】
题目链接:https://www.luogu.org/problemnew/show/P1474 题目描述 母牛们不但创建了它们自己的政府而且选择了建立了自己的货币系统.由于它们特殊的思考方式,它们对 ...
- Linux 运行Python文件,不因终端关闭而终止运行
在Linux服务器运行py文件时,有时会因为终端窗口的关闭而结束py文件的执行,这时候使用下面的命令运行py文件: $nohup python filename.py & 命令解释: nohu ...
- 使用 P6Spy 来格式化 SQL 语句,支持 Hibernate 和 iBATIS
事情起因 在处理一个查询小功能的时候,自认为 SQL 语句和传参均正确,然而查询结果无匹配数据,在查看 Hibernate 自带 SQL 语句输出的时候带着问好感觉有点不爽,特别是想复制 SQL 语句 ...
- pom.xml将jar包导入
2.5是Maven的版本
- iptables防火墙企业级模板
目前公司业务已大多迁移至内网使用或者使用云主机,防火墙也渐渐不用了,在博客上记录一下,以免以后突然有用却找不到模板了.此防火墙脚本执行时默认清空旧的防火墙规则.放行本地loop网卡,DNS服务,NTF ...
- python测试开发django-49.allow_tags和mark_safe
前言 前面一篇使用allow_tags方法可以在xadmin的后台页面中插入html代码,在2.x版本ModelAdmin里面删除了allow_tags属性的支持,使用mark_safe函数代替 al ...
- VC++网络安全编程范例(11)-SSL高级加密网络通信(转)
SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议.TLS与 ...