如果我们声明一个对象并将其分配给同一个类的另一个对象,会发生什么

时间:2016-03-27 07:40:33

标签: java c++ memory-management garbage-collection jvm

C ++中的代码

class FirstClass
{
    public:
        int var;
};

int main()
{
    FirstClass A, B;
    A.var = 10;
    B.var = 20;

    cout << "Address of A : " << &A << endl;
    cout << "A.var : " << A.var << endl << endl;

    cout << "Address of B : " << &B << endl;
    cout << "B.var : " << B.var << endl << endl;

    A = B;

    cout << "Address of A : " << &A << endl;
    cout << "A.var : " << A.var << endl << endl;

    cout << "Address of B : " << &B << endl;
    cout << "B.var : " << B.var << endl << endl;
}

输出:

A的地址:0x28fefc

A.var:10

B的地址:0x28fef8

B.var:20

A的地址:0x28fefc

A.var:20

B的地址:0x28fef8

B.var:20

我知道内存和var的值是怎么回事。与上面的代码没有混淆。重点是内存保持不同,两个对象仍然指向相同的旧内存位置。意味着没有未引用的记忆。

Java代码;

public class FirstClass
{
    public int var;
}


public class SecondClass
{
    public static void main(String str[])
    {
        FirstClass A = new FirstClass();
        FirstClass B = new FirstClass();

        A = B;      
    }
}

做同样的事情,我在上面的C ++代码中做了。 为什么这次垃圾收集器会起作用,做A = B为什么我们会得到一个未引用的记忆。

4 个答案:

答案 0 :(得分:3)

让我们更改您的代码只是为了提供更多背景信息:

FirstClass A = new FirstClass(1);
FirstClass B = new FirstClass(2);

此时,FirstClass(1)FirstClass(2)不符合GC的条件,因为范围内有两个当前指向这些实例的变量。但是,当您执行以下行时:

A = B;

你使AB指向FirstClass(2)和&#34;没有&#34;指向FirstClass(1) ...因为那里没有&#34;没有&#34;指向它,FirstClass(1)有资格获得GC。

Java中的变量有两种。它们既可以是原始类型(例如intboolean),也可以是Object类型。原始值总是在赋值时复制,但对象变量就像C ++中的指针一样。如果您将一个Object变量分配给另一个变量,那么您只需更改它指向的内存位置,而不是创建一个新的&#34;复制的&#34;目标的实例。

答案 1 :(得分:2)

这是C ++和Java的不同之处。在C ++中将一个对象分配给另一个对象时,它会将一个对象的值复制到另一个对象。而在Java中,它会声明A引用B指向的对象。由于现在JVM已经丢失了对B的引用并且它不再可达,它就成为GC的合格候选者。

答案 2 :(得分:2)

在Java中,AB确实是指针。但是在你的C ++代码中,它们不是。这是唯一的区别。

如果将C ++ AB更改为指针,您将看到这两段代码现在是等效的:

FirstClass* A = new FirstClass;
FirstClass* B = new FirstClass;
A->var = 10;
B->var = 20;

A = B;

现在A = B复制指针,而不是指向对象,就像在Java中一样。

答案 3 :(得分:2)

java中的普通对象创建

SomeClass obj = new SomeClass();

如上所示,当您使用java中的new关键字创建新对象时,JVM会在堆区域中分配所需的内存,并将该内存区域分配给给定的引用变量,obj在我们的示例中。因此,在您的情况下,它为2个对象分配内存,并为相应的引用变量分配引用。

当你做的时候

A = B;

我们正在指示JVM分配内存引用,由B引用变量A.所以,现在A和B都指向相同的内存区域。在执行赋值语句之前,其他内存区域(实际上由A指向)未被任何引用指向,因此有资格进行垃圾回收