欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JAVA中的引用与对象详解

程序员文章站 2024-03-07 17:24:51
thinking in java 一书中提到,引用和对象就像瑶控器和电视机。用瑶控器(引用)来操作电视机(对象),想换频道什么的直接操作瑶控器就可以了,瑶控器再来调控电视机...

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()创建了两个对象。

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