繁体   English   中英

内存中的Java原始类型和对象结构

[英]Java primitive types and objects structure in memory

当我们创建 Java 原始变量或 Java 对象时,它是如何在内存中表示/结构化的?

int A;

// 是否创建了对整数类型的引用?
// 保存在内存中分配的整数类型所需的内存空间吗?

A = 3;

// 现在是否分配了保存整数类型所需的内存空间? 然后A引用那个空间。

int B = 2;
A = B;

// A 是否将内存位置引用为 B ? 而 A 引用的旧内存位置是 Garbage Collected ?
// 如果是,那么修改 A 将导致也修改 B,对吗?
// 如果没有,那么已经完成了传值。
// 是否修改了 A 引用的内存位置,或者创建了一个能够保存 int 的新内存位置,填充了 B 引用的值,然后被 A 引用?

如果 A 是一个类对象,是否也有相同的类比?

Java 中的原语进入堆栈,因此它们存储在变量的位置。 请记住,虽然 String 被认为是不可变的,但它不是原始类型,而是一个类。

因此变量 A 和 B 都持有值 2,但不共享该值。 附带说明一下,Java 对 int 变量做了一些有趣的事情。 如果它们足够低,它们实际上甚至不会存储在堆栈中,而是引用内存中的静态分配(预编译器处理)。

现在对于您要分配类实例的部分。 然后事情发生了一些变化。 如果您将实例分配给 A,您将在堆栈上分配对 A 的引用并在堆上分配它。 当您将 A 分配给 B 时,两者都将引用堆中的同一个实例。 在两个引用都超出范围之前,不会对该实例进行垃圾回收。

如果您重新分配 A 或 B,它们将不再指向堆中的同一个实例。

在您的场景中,在堆栈上进行的内存管理:不在堆上,可以描述如下: 在此处输入图片说明

当你这样做时, A=B ,为A引用的整数分配的内存变得有资格进行 GC。

现在,当您对任一变量进行修改时,您正在引用与该值对应的其他内存位置,并且由于它在堆栈上,因此不会影响另一个。

例如,做A = 6 ,不会影响B的值; B 仍然保持值为2

最后,它与如果 A 是类对象的情况不同,因为对象进入堆内存。

看看这篇Wiki文章,我发现它的解释性很强。

每种类型的数据类型都有不同的数据量,用于存储该数据类型,这就是为什么我们对大小有限制,例如,整数可以是(-2,147,483,648 到 2,147,483,647,最多 32位)。 其他数据类型,例如 floats 和 doubles,具有不同的值,其中 float 是 32 位浮点值,double 是 64 位双精度浮点值。

至于你的问题,如果你改变B,它会改变A,简短的回答是否定的。 当您定义一个等于 B 的变量 A 时,您所做的是将 A 的值更改为等于 B。另一个例子,如果您有以下代码(任何面向对象的语言),您在做什么正在内存中创建一个值为零的位置(并分配了 32 位的空间),并且您正在创建第二个变量,其值为变量a ,该值为零。 编辑:第二个变量完全独立于第一个。

int a = 0;
int b = a;

有这样一种东西,可以通过改变原始值来修改一个变量,这就是所谓的指针。 指针是一种特殊的小工具,用于保存有关数据存储在内存中的位置的信息,也称为内存地址。 看看下面的代码。

Person* person = new Person();
int* age = person.age;

在这里,我声明了两个指针,一个是对正在实例化的对象的引用,另一个是指向该对象中的字段的链接。 指针存储给定数据在内存中存储位置的信息(内存地址)。 由此,每当使用指针时,它都充当指向该内存地址的指针供我们访问。 因此,它并不是真正的变量,而是充当“目录”中的列表,您可以在其中使用它来查找数据。 因为它不直接存储任何数据,而只是对存储数据的引用,当直接用person.age改变人的年龄时,它也会更新内存中的数据,但地址保持不变,并且将反映在指针上。

至于垃圾收集的问题,在 Java 或 C# 等语言中,只有在不再引用该信息时才会对数据进行垃圾收集。 但是,在 C++ 等语言中,不会自动进行垃圾回收,您必须删除使用delete关键字创建的指针。

无论如何,希望这会有所帮助!

对于原始类型:

int i = 10;
int j = i;
i = 11

在 java 中,为 i 和 j 的值分配了 8 字节的内存(i 为 4 字节,j 为 4 字节)。 i 的值传递给 j,现在 j 和 i 具有相同的值但不同的内存地址。 现在 i 的值更改为 11,这意味着对于相同的内存地址,i 的值从 10 更改为 11,但 j 的值位于不同的内存位置,因此它保持为 10。

在此处输入图片说明

在对象的情况下,值(或引用)本身是一个地址(或堆地址),所以如果一个人改变了它,它也会反映给其他人。 例如在对象中:-

Person p1 = new Person();
Person p2 = p1;

在此处输入图片说明

因此,无论是 p1 进行更改还是 p2 进行更改,两者都会更改。 无论是 Java、Python 还是 Javascript,它都是一样的。 在原始值的情况下,它是实际值,但在对象的情况下,它是实际对象的地址 - 这就是技巧。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM