java堆,栈,常量池最通俗易懂的图文解释

2023-11-13

转自:http://www.iteye.com/topic/634530


1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.
2. 栈(stack):存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。)
3. 堆(heap):存放所有new出来的对象。
4. 静态域:存放静态成员(static定义的)
5. 常量池:存放字符串常量和基本类型常量(public static final)。
6. 非RAM存储:硬盘等永久存储空间

这里我们主要关心栈,堆和常量池,对于栈和常量池中的对象可以共享,对于堆中的对象不可以共享。栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会消失。堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。
对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。
如以下代码:
Java代码  
  1. String s1 = "china";  
  2. String s2 = "china";  
  3. String s3 = "china";  
  4. String ss1 = new String("china");  
  5. String ss2 = new String("china");  
  6. String ss3 = new String("china");  



 

这里解释一下黄色这3个箭头,对于通过new产生一个字符串(假设为”china”)时,会先去常量池中查找是否已经有了”china”对象,如果没有则在常量池中创建一个此字符串对象,然后堆中再创建一个常量池中此”china”对象的拷贝对象。这也就是有道面试题:String s = new String(“xyz”);产生几个对象?一个或两个,如果常量池中原来没有”xyz”,就是两个。



对于基础类型的变量和常量:变量和引用存储在栈中,常量存储在常量池中。
如以下代码:

Java代码  
  1. int i1 = 9;  
  2. int i2 = 9;  
  3. int i3 = 9;   
  4. public static final int INT1 = 9;  
  5. public static final int INT2 = 9;  
  6. public static final int INT3 = 9;  




对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量;局部变量就是方法或语句块内部定义的变量。局部变量必须初始化。
形式参数是局部变量,局部变量的数据存在于栈内存中。栈内存中的局部变量随着方法的消失而消失。
成员变量存储在堆中的对象里面,由垃圾回收器负责回收。
如以下代码:
Java代码  
  1. class BirthDate {  
  2.     private int day;  
  3.     private int month;  
  4.     private int year;      
  5.     public BirthDate(int d, int m, int y) {  
  6.         day = d;   
  7.         month = m;   
  8.         year = y;  
  9.     }  
  10.     省略get,set方法………  
  11. }  
  12.   
  13. public class Test{  
  14.     public static void main(String args[]){  
  15. int date = 9;  
  16.         Test test = new Test();        
  17.            test.change(date);   
  18.         BirthDate d1= new BirthDate(7,7,1970);         
  19.     }    
  20.   
  21.     public void change1(int i){  
  22.         i = 1234;  
  23.     }  



}


对于以上这段代码,date为局部变量,i,d,m,y都是形参为局部变量,day,month,year为成员变量。下面分析一下代码执行时候的变化:
1. main方法开始执行:int date = 9;
date局部变量,基础类型,引用和值都存在栈中。
2. Test test = new Test();
test为对象引用,存在栈中,对象(new Test())存在堆中。
3. test.change(date);
i为局部变量,引用和值存在栈中。当方法change执行完成后,i就会从栈中消失。
4. BirthDate d1= new BirthDate(7,7,1970);  
d1为对象引用,存在栈中,对象(new BirthDate())存在堆中,其中d,m,y为局部变量存储在栈中,且它们的类型为基础类型,因此它们的数据也存储在栈中。day,month,year为成员变量,它们存储在堆中(new BirthDate()里面)。当BirthDate构造方法执行完之后,d,m,y将从栈中消失。

5.main方法执行完之后,date变量,test,d1引用将从栈中消失,new Test(),new BirthDate()将等待垃圾回收.

**************************************************************************************************************************

   Integer e = 321;    

  Integer f = 321;    

   System.out.println(e==f);   //false  结果

   结果:由于321不是在范围内所以不是从缓存中取数据的而是单独有new对象,e和f并没有指向同一个对象,结果为false

在自动装箱时,把int变成Integer的时候,是有规则的,当你的int的值在-128-IntegerCache.high(127) 时,返回的不是一个新new出来的Integer对象,而是一个已经缓存在堆 中的Integer对象,(我们可以这样理解,系统已经把-128到127之 间的Integer缓存到一个Integer数组中去了,如果你要把一个int变成一个Integer对象,首先去缓存中找,找到的话直接返回引用给你就 行了,不必再新new一个),如果不在-128-IntegerCache.high(127) 时会返回一个新new出来的Integer对象。

包装类数据,如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中,Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。

==比较的是对象的地址,也就是是否是同一个对象;

equal比较的是对象的值。

int 变为Integer 时  如果值在-128~127之间  则不会创建新的integer对象 储存常量池中,这么做的目的是提高效率----->记得在别的地方看过不知道对不对

**************************************************************************************************************


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java堆,栈,常量池最通俗易懂的图文解释 的相关文章

随机推荐

  • java设置有时效的变量_java设置全局变量

    图片来源于网络 如有侵权请联系删除 前言 java系统自带的api很多 而设置全局变量也是有在System对象中一个具体的方法 而Springboot启动类一层层递进的过程中就有使用该方法来存储全局变量 1 实例 在Springboot中的
  • MAC Unity安装教程

    缘起 这边app要做一个简单调研 验证是否可以利用unity改善app中h5页面需要展示的3d和复杂报表效果 于是就此开始了调研 这边只是想简单将unity集成到工程中 然后想办法嵌入h5来进行展示测试 安装地址 https unity3d
  • Java:字符串中a出现的次数

    1 问题描述 求字符串 abcguegduauwdakolaa 中a出现的次数 2 题解 2 1 题解一 思路 每次返回当前下标 使用indexOf求当前下标的后一位到字符串结束出现的第一个a的下标 String s abcguegduau
  • JS的防抖函数理解、手动封装

    1 认识防抖函数 当事件触发时 相应的函数并不会立即触发 而是会等待一定的时间 当事件密集触发时 函数的触发会被频繁的推迟 只有等待了一段时间也没有事件触发 才会真正的执行响应函数 举个例子 防抖函数的引用场景 输入框中频繁的输入内容 搜索
  • 网站开发之DIV+CSS简单布局网站入门篇(五)

    这篇文章主要介绍如何使用DIV和CSS简单布局一个网站的首页 通常将网站划分为顶部 Logo 导航条 中部 页面主要内容 左右栏目 底部 制作方介绍 超链接 这是非常基础的一篇引入性文章 采用案例的方式进行介绍的 希望对你有所帮助 运行结果
  • elementUI的日期选择器获取选择时间的格式,获取时间戳等

    elementUI的日期选择器获取选择时间的格式 获取时间戳等 在使用日期选择器的时候 我们需要把时间进行格式化 然后再传给后端 比如传时间戳 value format timestamp
  • RAID(磁盘阵列)

    一 RAID的简述 RAID是英文 Redundant Array of Independent Disks 的缩写 翻译成中文是 独立磁盘冗余阵列 简称磁盘阵列 Disk Array 简单的说 RAID是一种把多块独立的硬盘 物理硬盘 按
  • vue 打印文件

    1 下载插件 npm install vue print nb save 2 全局注册 在main js 中引入 打印文件 import Print from vue print nb Vue use Print 3 需要打印部分设置 id
  • 三种通信方式——单工、半双工和双工通信

    数据通常是在两个站 点对点 之间进行传输 按照数据流的方向可分为三种传输模式 单 工 半双工 全双工 一 单工通信 simplex 单工通信只支持信号在一个方向上传输 正向或反向 任何时候不能改变信号的传输方向 为保证正确传送数据信号 接收
  • 锐捷6800 vrrp mstp配置实例

    直接把配置考出来了 大家先看看把 6810A show run System software version 2 42 5 Build Feb 2 2007Rel Building configuration Current config
  • 使用SSH远程连接安卓手机Termux - Android手机服务器

    文章目录 1 安装ssh 2 安装cpolar内网穿透 3 远程ssh连接配置 4 公网远程连接 5 固定远程连接地址 转载自cpolar极点云的文章 公网SSH远程连接Termux 电脑使用安卓Termux 无需公网IP 使用安卓机跑东西
  • 常用算法与设计模式

    时间复杂度 二 计算方法 1 一个算法执行所耗费的时间 从理论上是不能算出来的 必须上机运行测试才能知道 但我们不可能也没有必要对每个算法都上机测试 只需知道哪个算法花费的时间多 哪个算法花费的时间少就可以了 并且一个算法花费的时间与算法中
  • Disconnected: No supported authentication methods available (server sent: publickey)

    安装Git客户端后 进行PULL时报如下错误 disconnected no supported authentication methods available server sent publickey keyboard interac
  • Spring:@Valid 和 @Validated

    Validated 常用于对 RequestBody注解中的参数校验生效 用法 PostMapping public UserModel getUser Validated RequestBody UserModel model retur
  • 关于暴力&瞎搞骗分的一些实例

    骗分的实质 不会做的题用最少的时间写代码得到最多的分数 下面是几个乱搞骗分的实例 抛砖引玉让大家感受下骗分的强大 1 NOI 2008 志愿者招募 http codevs cn problem 1803 根据题目范围可以想到直接搜索骗分 期
  • 中职网络安全2022国赛之MS12020漏洞扫描与利用(CVE-2012-0002)

    简介 我做了一个简单的环境来复现这个漏洞 需要虚拟机环境的可以加我qq 3316735898 有什么不会的也可以问我 1 在MSF工具中用search命令搜索MS12020 RDP拒绝服务攻击模块 将回显结果中的漏洞披露时间作为Flag值
  • 手把手教你制作一块Linux开发板(基于Planck-pi)

    文章目录 前言 一 前期准备 二 焊接部分 三 镜像烧写部分 总结 前言 攻城狮星河 Hello 各位野生钢铁侠们 这篇文章初衷是帮助想自己制作linux小板子的小白们 文中会讲的比较基础 大佬勿喷 本教程会以稚晖君开源的 planck p
  • Win7下的C语言开发环境

    本文参考至 http jingyan baidu com article 870c6fc32fa08fb03fe4beae html
  • APS自动排产在企业生产中的应用:生产整体优化

    APS系统 又名高级计划与排程 Advanced Planning and Scheduling 企业管理软件 是对所有资源具有同步的 实时的 具有约束能力的 模拟能力 不论是物料 机器设备 人员 供应 客户需求 运输等影响计划因素 不论是
  • java堆,栈,常量池最通俗易懂的图文解释

    转自 http www iteye com topic 634530 1 寄存器 最快的存储区 由编译器根据需求进行分配 我们在程序中无法控制 2 栈 stack 存放基本类型的变量数据和对象的引用 但对象本身不存放在栈中 而是存放在堆 n