Java如何将变量名与内存中的位置相关联?

Java如何将变量名与内存中的位置相关联?,java,memory-management,Java,Memory Management,Java如何将变量名与内存中的位置相关联 我的第一个想法是,必须有一个用于所有变量名的静态表,它将变量名与它的值或它的值的位置相关联。它存在吗?这个表有正式名称吗?原语类型变量的值是一些数字,引用类型变量的值是引用(通常是内存地址) 现在的问题是:给定变量的存储值在哪里。它取决于变量的类型-有局部变量、实例变量(字段)和类变量(静态字段) 在编译过程中解析局部变量的名称。每个变量在方法中成为简单的第i个变量,它将作为第i个变量存储在某个方法调用的堆栈框架中 例如,它将是不同的。字段名总是出现在字

Java如何将变量名与内存中的位置相关联


我的第一个想法是,必须有一个用于所有变量名的静态表,它将变量名与它的值或它的值的位置相关联。它存在吗?这个表有正式名称吗?

原语类型变量的值是一些数字,引用类型变量的值是引用(通常是内存地址)

现在的问题是:给定变量的存储值在哪里。它取决于变量的类型-有局部变量、实例变量(字段)和类变量(静态字段)

在编译过程中解析局部变量的名称。每个变量在方法中成为简单的第i个变量,它将作为第i个变量存储在某个方法调用的堆栈框架中

例如,它将是不同的。字段名总是出现在字节码中(但通常不会出现在JIT编译器生成的机器代码中)。给定类的所有对象都具有相同的布局,所以该类可以存储给定场距对象起点的偏移量。解释器可以读取对象的地址并添加偏移量来计算变量存储的位置


类变量类似于实例变量,但更简单。在这种情况下,类存储其变量的名称和值。

历史上的编译包括创建一个符号表,该符号表将变量名称与其根据源代码确定的属性相关联。为了便于说明,这有点过于简单,但由于FORTRAN很有用,所以原则没有改变。诸如C++和java语言中的用户定义类型构成编译单元收集的每个编译单元的元数据的一部分,当运行时可执行文件被创建或加载到内存中时,它们被编织在一起。 请注意,必须先定义所有类型,然后才能使用它们定义类型的对象。这就是Java中“导入”和C/C++中“包含”的目的。元数据包括方法和对象(或类)数据元素的定义,用于确定要在静态内存、堆栈(块入口/出口)或堆(动态分配)中创建的对象的大小

编译时或执行期间的类型检查是过去四十年中最重要的发展之一,也是我们能够在火星、加利福尼亚高速公路或互联网上使用自主机器人的主要原因。编程语言编译或翻译的核心问题是跟踪关于对象的所有已知信息,并将其放入内存中,以便在运行时正确使用


像FORTRAN和COBOL这样的古代语言有一种变量类型(静态),它只有基本的数据类型属性。他们有几乎微不足道的符号表。最复杂的问题是将编译单元链接在一起执行。我们已经走了很长的路,宝贝

也许这会有所帮助:除非您自己实现JVM,否则您不需要分配或跟踪变量的确切内存位置。变量名必须以某种方式限定,因为您可以在不同的类中使用相同名称的变量,但也在同一个类或方法中,但在不同的范围内;我的猜测(基于查看一些字节码)是变量名只与编译器相关;你的程序是用字节码重写的,字节码只根据变量在堆栈上的位置引用变量。你似乎把重点放在了实际对象的存储位置上。但是变量和对象之间的连接是如何发生的呢?在内存中必须有某个地方,变量保存有关其对象或原语位置的数据。在编译过程中,字段和局部变量名解析为表偏移量。在运行时,变量由其包含的stackframe/instance/class(用于静态)所有,但没有指向它的链接——它们不需要这样做。没有在stackframe/instance/etc容器之外访问的变量。问题是关于Java和内存管理,即运行时,这里没有任何实际的答案。相反,所有这些都是大约90%不相关的,包括一个奇怪的断言,即“核心问题是。。。编译是跟踪关于对象的所有知识。这是最简单的部分。解析和代码生成是核心问题。这个问题没有提到内存管理。这表明我对计算机科学知之甚少,我扔掉了一堆关键词,希望你能四处看看,学到一些东西。这个问题没有提到内存管理。我扔了一堆关键词,希望你能四处看看,学到一些东西。在所有类型的程序中使用的数据内存一般有三种:静态内存为每个变量使用一个存储单元。大小由变量类型决定。高级语言还在语句的文本块中提供局部变量。高级技术采用动态内存分配—信息存储在一个称为“堆”的内存“池”中。存储的名称分配取决于使用的是哪一个。您不能生成代码来操作无法定义的内容。解析是在20世纪70年代用LALR(1)等解决的。