JAVA中的引用与对象详解

所属分类: 软件编程 / java 阅读数: 32
收藏 0 赞 0 分享

Thinking in Java 一书中提到,引用和对象就像瑶控器和电视机。用瑶控器(引用)来操作电视机(对象),想换频道什么的直接操作瑶控器就可以了,瑶控器再来调控电视机。如果你在房间里面走动,同时还想操作电视换频道,你只需要携带瑶控器就可以了。我觉得这个比较非常好,引用是用来操作对象的,对象是由你来创建的。通常用new关键字来创建一个对象。那么这些对象是怎样存储的,内存又是怎样分配的呢?

存储在什么地方?

1.寄存器(register):由于寄存器是在CPU内部的,所以它的速度最快,但是数量有限,所以由编译器根据需求进行分配。

2.栈(stack):位于通用RAM中,通过栈指针的移动来分配和释放内存,指针向下移动分配新的内存;指针向上移动则释放内存。速度仅次于寄存器。创建程序时,Java编译器必须知道存储在栈内所有数据的确切大小和生命周期,因为它必须生成相应的代码,以便上下移动栈指针,这就限制了程序的灵活性。所以java中的对象并不存放在栈当中,但对象的引用存放在栈中。

3.堆(heap):也是位于RAM中的内存池,用于存放所有的JAVA对象。编译器不需要知道要从堆里分配多少存储区域,也不需要知道存储的数据在堆里面存活多长时间,因此堆要比栈灵活很多。当你new创建一个对象时,编译器会自动在堆里进行存储分配。当然,为这种灵活性必须要付出相应的代码。用堆进行存储分配比用栈进行存储存储需要更多的时间。

4.静态存储(static storage):这里的“静态”是指“在固定的位置”(也在RAM里)。静态存储里存放程序运行时一直存在的数据。你可用关键字static来标识一个对象的特定元素是静态的,即存放类中的静态成员,但JAVA对象本身从来不会存放在静态存储空间里。

5. 常量存储(constant storage):存放字符串常量和基本类型常量(public static final)。常量值通常直接存放在程序代码内部,它们永远不会被改变。有时,在嵌入式系统中,常量本身会和其他部分分割离开,所以在这种情况下,可以选择将其放在ROM中。

简单描述下垃圾回收机制

垃圾回收回收的是无任何引用的对象占据的内存空间(堆)而不是对象本身,要注意以下3点:

1)对象可能不会被回收,即垃圾回收不一定会执行;

2)垃圾回收并不等于析构;

3)垃圾回收只与内存有关。

引用计数器:一种简单但是速度很慢的垃圾回收策略。即每个对象都有一个引用计数器,当有引用连接至对象时计数器加1;当引用离开时计数器减1。垃圾回收器会在含有全部对象的列表中遍历,发现某个对象的引用计数器为0时,就释放其占用的内存。

优点:引用计数收集器可以很快的执行,交织在程序运行中。对程序不被长时间打断的实时环境比较有利。

缺点:无法检测出循环引用。如父对象有一个对子对象的引用,子对象反过来引用父对象。这样,他们的引用计数永远不可能为0。

自适应、分代的、停止——复制、标记——清扫 垃圾回收方法:

停止——复制:先暂停程序的运行,然后将所有活的对象从当前堆复制到另一个堆,没有被复制的都是垃圾。当对象从一个堆复制到另一个堆,它们的排列是一个挨着一个的,所以新堆保持紧凑排列。

标记——清扫:遍历所有的引用,找出所有活的对象,然后对它们进行标记,这个过程不会回收任何对象,只有全部标记工作完成时才开始清除工作。没有被标记的对象将会被释放,不发生任何复制动作,所以剩下的堆空间不是连续的。

创建了几个对象?

String s="abc"; 创建了几个对象?

毫无疑问,这里面只创建了一个对象——“abc";

String s1="abc"; String s2=s1;创建了几个对象?

仍然只有一个对象——“abc";

String s1="abc"; String s2=”abc";创建了几个对象?

这里仍然只有一个对象——“abc";

String s="abc"+"def";创建了几个对象?

注意,这里创建了三个对象:“abc"、”def"、“abcdef";

String s=new String("abc");创建了几个对象?

大家也都知道是两个对象。实际上是"abc"本身就是文字池中的一个对象,在运行new String()时,把文字池即pool中的字符串"abc"复制到堆中,并把这个对象的应用交给s,所以创建了两个String对象,一个在pool中,一个在堆中。

String s1=new String("abc");String s2=new String("abc");创建了几个对象?

三个对象。"abc"是文字池中的一个对象,然后又在堆中用new String()创建了两个对象。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持脚本之家!

更多精彩内容其他人还在看

JavaWeb项目部署到服务器详细步骤详解

这篇文章主要介绍了JavaWeb项目如何部署到服务器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

IDEA基于支付宝小程序搭建springboot项目的详细步骤

这篇文章主要介绍了IDEA基于支付宝小程序搭建springboot项目的详细步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

详解SpringBoot应用服务启动与安全终止

这篇文章主要介绍了SpringBoot应用服务启动与安全终止,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Spring Boot启动及退出加载项的方法

这篇文章主要介绍了Spring Boot启动及退出加载项的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

Spring Data Jpa 自动生成表结构的方法示例

这篇文章主要介绍了Spring Data Jpa 自动生成表结构的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

IDEA中osgi的开发应用指南详解

这篇文章主要介绍了IDEA中osgi的开发应用指南详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

详解用maven将dubbo工程打成jar包运行

这篇文章主要介绍了详解用maven将dubbo工程打成jar包运行,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

详解Java合并数组的两种实现方式

这篇文章主要介绍了Java合并数组的两种实现方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
收藏 0 赞 0 分享

使用Jenkins Pipeline自动化构建发布Java项目的方法

这篇文章主要介绍了使用Jenkins Pipeline自动化构建发布Java项目的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

使用Maven配置Spring的方法步骤

这篇文章主要介绍了使用Maven配置Spring的方法步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多