人们常说堆栈堆栈,堆和栈是内存中两处不一样的地方,什么样的数据存在栈,又是什么样的数据存在堆中?

这里浅谈Java中的栈和堆

首先,将结论写在前面,后面再用例子加以验证。

Java的栈中存储以下类型数据,栈对应的英文单词是Stack

基本类型

引用类型变量

方法

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。

栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄。

栈有一个很重要的特殊性,就是存在栈中的数据可以共享。

Java的堆中存储以下类型数据,堆对应的英文单词是Heap

实例对象

在函数中定义的一些基本类型的变量(8种)和对象的引用变量都是在函数的栈Stack内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。

堆Heap内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。

引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因,实际上,栈中的变量指向堆内存中的变量,这就是 Java 中的指针!

class Person {int age;}public class LearnHeap {public static void main(String args[]){int a=10;Person person = new Person();person.age =20;change(a,person);System.out.println("a="+ a+",and person.age = "+person.age);}static void change(int a1, Person person){a1 = 11;person.age= 21;System.out.println("a1="+ a1+",and age1 = "+person);}}

  两次的输出结果是什么?猜测下。

以上程序内存加载的执行步骤:

第1步 —— main()函数是程序入口,JVM先执行,首先将main方法压入栈中,在栈内存中开辟一个空间,存放int类型变量a,同时附值10。
      在堆中分配一片区域,用来存放和创建Person对象,这片内存区域会有属于自己的内存地址,假设是1001,然后给成员变量赋值,age=20
      执行结束后,构造防范弾栈,Person创建完成,将Person的内存地址1001赋值给person(此处person小写,是引用变量类型)

第2步 —— JVM执行change()函数,在栈内存中又开辟一个新的空间,存放int类型变量a和对象Person中person
     此时main空间与change空间并存,同时运行,互不影响。

第3步 —— change()方法执行,将a赋值为11,person对象的堆中年龄age赋值为21

第4步 —— change()执行完毕,变量a立即释放,空间消失。但是main()函数空间仍存在,main中的变量a仍然存在,不受影响。而person在堆中对应的地址,所指的age已经赋值=21

实际输出如下:

结论:

如果a()方法中的基本类型(8个)变量x传入b()方法中,并在b()中进行了修改,则a()方法中的x的值保持不变 
如果a()方法中的引用类型        变量x传入b()方法中,并在b()中进行了修改,则a()方法中的x的值与b()保持一致

下面对8中基本类型进行简单的测试

package heapandStack;public class LearnHeap02 {public static void main(String args[]){byte b=10;short s=20;int i=30;long l =40l;float f =12.34f;double d = 100.123d;char c = 'A';boolean flag = true;change(b,s,i,l,f,d,c,flag);System.out.println(b);System.out.println(s);System.out.println(i);System.out.println(l);System.out.println(f);System.out.println(d);System.out.println(c);System.out.println(flag);}static void change(byte a, short b, int c,long d, float f, double g, char h,boolean x){a =11;b=21;c =31;d =41l;f=12.99f;g= 200.123d;h ='V';x =false;System.out.println(a);System.out.println(b);System.out.println(c);System.out.println(d);System.out.println(f);System.out.println(g);System.out.println(h);System.out.println(x);}
}

  

下面测试一下数组,是不是属于实例对象类型

public class LearnHeap03 {public static void main(String args[]){int a[] ={1,2,3};change(a);for(int i:a)System.out.print(i+" ");}static void change(int[] a){a[0]=4;a[1]=5;for(int i:a)System.out.print(i+" ");System.out.println("============ ");}
}

  从结果看出,数组的值被改变了

Java种8种基本数据类型,并不包含String,String的值会被change函数改变吗?String应该存在栈中,还是堆中呢?

先直接上测试代码

public class Learn04 {public static void main(String args[]){String s1 = new String("abcd");String s2 = "asdfghjkl";System.out.println(s1+", "+s2);change(s1,s2);System.out.println(s1+", "+s2);}static void change(String s1,String s2){s1 ="123456";s2 ="000000";System.out.println(s1+", "+s2);}
}

两种的形式来创建String,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。 而第二种是先在栈中创建一个对String类的对象引用变量s2,然后查找栈中有没有存放"asdfghjkl",如果没有,则将"asdfghjkl"存放进栈,并令str指 向”abc”,如果已经有”asdfghjkl” 则直接令s2指向“asdfghjkl”。  

 

既然讲到两种形式创建String,下面讲一个String两种形式创建的区别,先看一段代码

public class Learn05 {public static void main(String args[]){String s1 = new String("abcd");String s2 = "abcd";boolean a =s1.equals(s2);boolean b =(s1==s2);System.out.println(a);System.out.println(b);String s3 = "abcd";boolean a1 =s3.equals(s2);boolean b1 =(s3==s2);System.out.println(a1);System.out.println(b1);}}

  

转载于:https://www.cnblogs.com/qianjinyan/p/10352749.html

浅谈Java中的栈和堆相关推荐

  1. java null什么意思_浅谈java中null是什么,以及使用中要注意的事项

    1.null既不是对象也不是一种类型,它仅是一种特殊的值,你可以将其赋予任何引用类型,你也可以将null转化成任何类型,例如: Integer i=null; Float f=null; String ...

  2. aba会导致问题_浅谈Java中ABA问题及避免

    本文主要研究的是关于Java中ABA问题及避免的相关内容,具体如下. 在<Java并发实战>一书的第15章中有一个用原子变量实现的并发栈,代码如下: public class Node { ...

  3. java 线程aba,浅谈Java中ABA问题及避免,浅谈javaaba避免

    浅谈Java中ABA问题及避免,浅谈javaaba避免 本文主要研究的是关于Java中ABA问题及避免的相关内容,具体如下. 在<Java并发实战>一书的第15章中有一个用原子变量实现的并 ...

  4. 浅谈java中的多态

    浅谈java中的多态 学习了java一年的时间,这里对java的多态进行了一个总结,如有错误希望可以指出, 首先java的多态分为编译时的多态和运行时的多态,其中编译时的多态就是方法的重载(前期绑定) ...

  5. java 中的单元测试_浅谈Java 中的单元测试

    单元测试编写 Junit 单元测试框架 对于Java语言而言,其单元测试框架,有Junit和TestNG这两种, 下面是一个典型的JUnit测试类的结构 package com.example.dem ...

  6. 浅谈Java中的Set、List、Map的区别

    就学习经验,浅谈Java中的Set,List,Map的区别,对JAVA的集合的理解是想对于数组: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型),JAVA集合可以存储和操 ...

  7. java中修饰常量的事_浅谈java中的声明常量为什么要用static修饰

    今天定义一个类常量,想着也只有这个类可以用到,就没用static关键字修饰.结果sonar代码检查提示: Rename this field "PERSON_TYPE_USER" ...

  8. 浅谈JAVA中如何利用socket进行网络编程(二)

    转自:http://developer.51cto.com/art/201106/268386.htm Socket是网络上运行的两个程序间双向通讯的一端,它既可以接受请求,也可以发送请求,利用它可以 ...

  9. scale和java比较_浅谈java中BigDecimal的equals与compareTo的区别

    这两天在处理支付金额校验的时候出现了点问题,有个金额比较我用了BigDecimal的equals方法来比较两个金额是否相等,结果导致金额比较出现错误(比如3.0与3.00的比较等). [注:以下所讲都 ...

最新文章

  1. duilib 修复Text控件无法设置宽度的bug,增加自动加算宽度的属性
  2. ZOJ 2317 Nice Patterns Strike Back(矩阵快速幂)
  3. 第三十二章 elk(3)- broker架构 + 引入logback
  4. php5.4 教程,linux php5.4 装置教程_后端开发
  5. 运维管理中的制度和流程
  6. Bailian2880 句中最长的单词【字符串】
  7. java B2B2C Springcloud电子商务平台源码 -Feign之源码解析
  8. sqlalchemy按月水平分表、python元类、动态映射表名automap_base\ 模型类
  9. 乌鲁木齐市建筑物矢量数据(Shp格式+带高度)
  10. Spark的调度系统
  11. 机械制图与计算机辅助绘图题,机械制图与计算机绘图作业题解ppt课件.ppt
  12. 网络协议之UDP数据包
  13. The Django Book-----第一章:介绍Django
  14. WORD文档转换成HTML
  15. netty Force-closing a channel whose registration task was not accepted by an event loop问题
  16. 【参赛作品31】openGauss和PostgreSQL的源码目录结构对比
  17. c语言 函数 引用调用,C 引用方式调用函数
  18. QNX系统终端中同一个进程号显示多次
  19. Linux shell实现阶乘
  20. 大话西游手游服务器维护要多久,大话西游手游:每周必看 2020年6月11日维护公告...

热门文章

  1. BSCI—7:OSPF的路由汇总
  2. 对Moss 2007中访问群体的设置和使用补充
  3. Centos启用rz/sz命令
  4. 《神探tcpdump第五招》-linux命令五分钟系列之三十九
  5. 一个smarty 分页插件
  6. 线路速度之实战***
  7. 2008年十大IT图书评选第一周幸运读者获奖名单(每周更新)
  8. list 分组求和_数据分析-python-分组聚合-2
  9. 32怎么通过一个按键实现不同工作模式_stm32几种低功耗模式的实现和差别
  10. 难道千元机的品质真的不如旗舰机吗?