昨天中午,发了一篇equals和==区别的博文,晚上再看时有几位大牛指出了其中的一些错误,很感谢他们的留言,一句简简单单的留言给了我对这些错误知识点改正的机会。或许这就是从事互联网行业所提倡的互帮互助的精神吧,因为有分享,有交流,互联网才会发展的如此迅猛。大牛提的一个观点很好,好的东西可以拿出来分享,错的东西却可能带给别人错误的理解,这一点我确实得向看了我写了一些bug博客的人道个歉。

针对大牛所指出的错误,晚上翻出了资料,重新温习了一遍。继续总结一下:

一、在JVM中,内存是如何被划分的?

java把内存分两种:一种是栈内存,另一种是堆内存

1. 在函数中定义的基本类型变量和对象的引用变量都在函数的栈内存中分配;(所以int的东西放在栈中)

2. 堆内存用来存放由new创建的对象和数组以及对象的实例变量。

在函数(代码块)中声明(这里并没有实例化)一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量所分配的内存空间;在堆中分配的内存由java虚拟机的自动垃圾回收器来管理

二、堆和栈的优缺点比较
1. 堆的优势是可以动态分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的;缺点就是要在运行时动态分配内存,存取速度较慢。

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

三、new出来的对象存在内存的什么地方?

在Java中,创建一个对象包括对象的声明和对象的实例化两部分。程序员需要通过关键字new为每个对象申请内存空间(基本类型除外),所有的对象都在堆(heap)中分配空间。

举例说明的一段代码
  1. public class NewTest {
  2. double aaa;
  3. double bbb;
  4. public NewTest(double aa,double bb){
  5. aaa = aa;
  6. bbb = bb;
  7. }
  8. }
public class NewTest {double aaa;double bbb;public NewTest(double aa,double bb){aaa = aa;bbb = bb;}
}

上面的这段代码,当我们使用NewTest test = new NewTest()时,我们做如下分析:

NewTest test : 声明一个对象test时,将在栈内存为对象的引用变量test分配内存空间,但NewTest的值为空,称test是一个空对象。空对象不能使用,因为它还没有引用任何"实体"。

test = new NewTest()时,在堆内存中为类的成员变量aaa,bbb分配内存,并将其初始化为各数据类型的默认值;接着进行显式初始化(类定义时的初始化值);最后调用构造方法,为成员变量赋值,返回堆内存中对象的引用(相当于首地址)给引用变量test,以后就可以通过test来引用堆内存中的对象了。

创建两个不同对象代码
  1. NewTest test1 = new NewTest();
  2. NewTest test2 = new NewTest();
NewTest  test1 = new NewTest();
NewTest  test2 = new NewTest();

在使用同一个类创建两个不同的对象的时候,这些对象实例将在堆中被分配到不同的内存空间,改变其中一个对象的状态不会影响其他对象的状态。

四、Java基本类型在内存中的存储

这里重点讨论一下八种基本类型(int, short, long, byte, float, double, boolean, char)在内存中时如何存放的。我们所指的八种基本类型定义的变量,是指形式如 int a=3、char aa ='a'类型的,即不通过new的。这里的aa时指向char类型的一个引用,指向'a'这个字面值。这些字面值的数据,由于大小可知,生存期可知(这些字面值定义在某个程序块里面,程序块退出后,字段值就消失了),出于追求速度的原因,就存在于栈中。

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

比如:我们同时定义:

long a =3;

long b =3;

编译器处理的过程是:

1. 编译器先处理long a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。

2. 接着处理long b = 3;在创建完b这个引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。

定义完a与b的值后,如果再令a = 4,这时,b不会等于4,还是等于3。在编译器内部,遇到时,它就会重新搜索栈中是否有4的字面值,如果没有,重新开辟地址存放4的值;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。

五、基本类型对应的包装类

基本类型都有对应的包装类:如int对应Integer类,double对应Double类等,基本类型的定义都是直接在栈中,如果用包装类来创建对象,就和普通对象一样了。例如:

int a=0;a直接存储在栈中。

Integer b= new Integer(5);b对象数据(这里指的是5)存储在堆中,b的引用存储在栈中,通过栈中的引用来操作对象。

六、String在内存中的存放

String是一个特殊的包装类数据,可以用用以下两种方式创建:

String str = new String("abc");第一种创建方式,和普通对象的的创建过程一样;

String str = "abc"; 第二种创建方式,类似于基本数据类型的创建,变量名和数据存放在栈空间中。

七、数组在内存中的存放

int x[] 或者int []x 时,在内存栈空间中创建一个数组引用,通过该数组名来引用数组。

x = new int[5] 将在堆内存中分配5个保存int型数据的空间,堆内存的首地址放到栈内存中,每个数组元素被初始化为0.

八、static变量在内存中的存放

用static的修饰的变量和方法,实际上是指定了这些变量和方法在内存中的"固定位置"-static storage,可以理解为所有实例对象共有的内存空间。static变量有点类似于C中的全局变量的概念;静态表示的是内存的共享,就是它的每一个实例都指向同一个内存地址。把static拿来,就是告诉JVM它是静态的,它的引用(含间接引用)都是指向同一个位置,在那个地方,你把它改了,它就不会变成原样,你把它清理了,它就不会回来了。

那静态变量与方法是在什么时候初始化的呢?

对于两种不同的类属性,static属性与instance属性,初始化的时机是不同的。instance属性在创建实例的时候初始化,static属性在类加载,也就是第一次用到这个类的时候初始化,对于后来的实例的创建,不再进行初始化。

转载于:https://blog.51cto.com/shuaigee/1131734

Java内存之栈与堆相关推荐

  1. Java内存分析—栈,堆,方法区

    Java内存分析-栈,堆,方法区 一.栈: 1).特点是:自动分配,连续空间,先进后出原则. 2).基本数据类型(一共有八种,char,byte,short,int,long,float,double ...

  2. 浅谈Java中的栈和堆

    人们常说堆栈堆栈,堆和栈是内存中两处不一样的地方,什么样的数据存在栈,又是什么样的数据存在堆中? 这里浅谈Java中的栈和堆 首先,将结论写在前面,后面再用例子加以验证. Java的栈中存储以下类型数 ...

  3. java什么是栈和堆_JAVA中的栈和堆

    JAVA在程序运行时,在内存中划分5片空间进行数据的存储.分别是:1:寄存器.2:本地方法区.3:方法区.4:栈.5:堆. 基本,栈stack和堆heap这两个概念很重要,不了解清楚,后面就不用学了. ...

  4. JAVA中的栈和堆的区别

    一.前言: 1.简介: 1.堆栈是两种数据结构,只能在一端对数据项进行插入和删除. 2.在单片机应用中,堆栈是个特殊的存储区,主要是暂时存放数据和地址. 3.堆,队列优先,先进先出 4.栈,先进后出 ...

  5. C++内存管理__内存管理(栈、堆(new/delete)、自由存储区(malloc/freee)、全局/静态存储区、常量区)!堆栈内存管理方式的区别

    内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄 ...

  6. 什么是java中的栈和堆_java中的堆和栈是什么?堆和栈有什么区别?

    java中的堆和栈是什么?堆和栈有什么区别? 发布时间:2020-06-02 11:51:19 来源:亿速云 阅读:183 作者:Leah java中的堆和栈是什么?堆和栈有什么区别?这些问题可能是我 ...

  7. 搞懂深浅拷贝JavaScript内存之栈和堆

    对于前端来说,平时开发业务代码的时候根本不会关心JavaScript的内存问题,因为根本用不到,也因此对于内存分配没有一点概念.只有理解了内存分配,对于深拷贝和浅拷贝才能真正理解.当然,理解内存分配对 ...

  8. 关于内存中栈和堆的区别[转]

    1.内存分配方面: 堆:一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式是类似于链表.可能用到的关键字如下:new.malloc.delet ...

  9. [ZZ]关于内存中栈和堆的区别

    1.内存分配方面: 堆:一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式是类似于链表.可能用到的关键字如下:new.malloc.delet ...

最新文章

  1. 四十九、深入了解两个并发接口Callable和Runnable的区别
  2. 公司技术部门内部的发展变化过程。
  3. MySQL 存储引擎(MyISAM、InnoDB、NDBCluster)
  4. wget整站抓取、网站抓取功能;下载整个网站;下载网站到本地
  5. Spring MVC-表单(Form)标签-下拉框(Dropdown)示例(转载实践)
  6. pcb外观维修_「维修案例」泰克AFG3021函数任意波形发生器故障维修
  7. 计算机语言中tc是什么,新人必须了解的几个TC常用语和脚本基础知识!
  8. [SpecialJudge]构造“神秘“字符串(洛谷P3742题题解,Java语言描述)
  9. [Axios] axios的基础语法
  10. uefi linux开发环境,开发者为 Linux 添加了一系列 RISC-V UEFI 支持补丁
  11. 数据库名、实例名、数据库域名、全局数据库名、服务名 我也迷糊了
  12. JS:ES10新特性
  13. MyEclipse 10.7(版本:eclipse 3.7.x-Indigo系列)安装activiti-eclipse-plugin插件(流程设计器)...
  14. 笔记本电脑计算机目录下无法显示视频设备,笔记本摄像头怎么开 win7笔记本摄像头打开方法...
  15. python3爬虫有道翻译_【Python3爬虫】有道翻译
  16. 微软输入法和搜狗输入法中的双拼
  17. Visio中图形关于轴线对称
  18. excel中创建随机数(包含英文+数字随机数生成)
  19. PYTHON 牛客刷题记录
  20. android客户端与服务器端交互 如何保持session

热门文章

  1. Non-Blind图像反卷积论文整理
  2. 这便是有三AI一年的底蕴,那些5000粉丝1000阅读量的AI技术干货
  3. “速卖通”店铺3天销量破零运营技巧
  4. 全球及中国生物医药产业供给需求前景与运营风险分析报告2022版
  5. 中国厨房家具行业消费需求调查与品牌格局分析报告2022版
  6. Ehcache缓存配置
  7. java pkcs#11读取证书加解密(初学-分享)
  8. 开放中国农业-国际农民丰收节贸易会:谋定全球共同发展
  9. 第四届泉水文化论坛协调会-商协社团:平台经济谋定水产业
  10. 悲观锁和乐观锁的详细分析