2014-03-13 60 views
3

对象在堆中的存储方式。例如,自行车类可以被定义如下:对象如何存储在堆中?

public class Bicycle { 

    public int gear; 
    public int speed; 

    public Bicycle(int startSpeed, int startGear) { 
     gear = startGear; 
     speed = startSpeed; 
    } 

    public void setGear(int newValue) { 
     gear = newValue; 
    } 

    public void applyBrake(int decrement) { 
     speed -= decrement; 
    } 

    public void speedUp(int increment) { 
     speed += increment; 
    } 
} 

然后我可以创建一个自行车对象:

Bicycle bicycle = new Bicycle(20,10) 

然后此自行车对象应被存储在堆。但我不明白堆是如何精确地存储这些实例变量和方法,如速度和齿轮。我明白堆应该实现为树。那么这个对象如何存储在树中?另外,当您使用bicycle.speed来查找速度的值时,会是什么时间复杂度?

+0

可能的重复[什么和堆栈和堆在哪里?](http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap) – EkoostikMartin

+0

@fge I了解堆应该作为树来实现。那么这个对象如何存储在树中? – Jude

+0

堆只是一个巨大的字节数组。一个对象是一个结构 - 一系列被视为单一实体并被分配在一起的字段。要创建一个对象,你需要找到一个合适大小的“空闲”堆,设置对象头(指向它的类的指针和其他一些“簿记”信息),并执行类中描述的初始化。 –

回答

4

希望别人做你的CS功课吧? ;)

根据不同的语言,确切的实现将有所不同(它如何存储在内存中),但一般概念是相同的。

你有你的堆栈内存和你的堆内存,局部变量和参数放在堆栈上,并且每当你进入堆中的东西。它被称为堆栈,因为当你声明它或调用一个函数时,值被推到它上面,然后弹出并且超出范围。

 
        +--------------+ 
|    | |    | 
|    | |    | 
|    | |    | 
|    | |    | 
|    | |    | 
|    | |    | 
+--------------+  
    Stack    Heap 

每个实例变量占用然而多少内存的类型做(取决于语言),编译器增加了这一切,这就是sizeof类型(点菜C++)。方法进入代码空间,并没有将new编辑到对象中(我认为现在你最好不要考虑这个问题,以了解内存是如何组织的,只要把它看作是魔法)。

所以在你的例子:

Bicycle bicycle = new Bicycle(20,10) 
  • bicycle是堆内存地址,今天参考大多数语言/系统将花费你在堆栈在32位和64位。
  • new在堆中分配内存。编译器计算出Bicycle的大小,并创建汇编/机器代码来分配它需要的内存量。

这是存储该行后的样子:

 
        +--------------+ 
|    | | Bicycle obj | 
|    | |--------------| 
|    | |    | 
|    | |    | 
|--------------| |    | 
| bicycle ref | |    | 
+--------------+  
    Stack    Heap 

更具体地说,由于自行车类有两个实例变量(或领域,他们被称为Java中),无一不是int S,而Java中的int是32位或4字节,您的Bicycle对象的大小是4个字节* 2个字段= 8个字节。

 
        +-------------+ 
|    | 0| gear  | 
|    | 4| speed  | 
|    | |-------------| 
|    | 8|    | 
|-------------| 12|    | 
| bicycle=0x4 | |    | 
+--------------+  
    Stack    Heap 

访问存储器的时间复杂度是O(1)。编译器能够计算出speed的确切内存地址,因为对象中的第二个int字段位于自行车+ 0x4处。

+0

谢谢你的解释,威尔!由于一个数据结构也被称为“堆”,我感到困惑。 http://stackoverflow.com/questions/1699057/why-are-two-different-concepts-both-called-heap这个链接也帮助我很多。我对你有一个问题:成员函数在哪里存储?它们是否也存储在堆中? – Jude

+0

成员函数存储在堆栈中@Jude – Kick

+0

是的堆ADT是完全不同的。我认为你需要在低层次的计算机体系结构中建立更多的知识,然后才有意义。 1.实际代码(字节代码或程序集)存储在别处的代码空间中。 2.在移动当前行指针之前,将参数值压入堆栈(带有一些回调/返回内存地址)。 3.堆中的物体保持原状,直到它们被销毁。如上图所示,引用实际上只是内存地址的一个整数。 –

1
Bicycle bicycle = new Bicycle(20,10) 

参考自行车将存储在stack而对象和实例变量将存储在heap和堆的地址在堆分配,这样的意思是说堆将链接到堆。

+0

据我所知,参考文献将在堆栈中。我不知道该对象是如何存储在堆中的。 – Jude

0

首先,你应该从Java方面理解Object的含义。

对象只不过是堆中的一个缓冲区(内存区域)。该缓冲区或内存区域称为对象。

Object包含该类的所有非静态数据成员。在堆

所有the-

对象存储。

静态数据成员存储在Class Area中。

参考变量存储在堆栈中。

方法(静态或非静态)存储在方法区域中。

Memory Area