class/instance 对象实际上如何从 Java/Objective C 中内存的 Text/Method 段访问方法?
How does a class/instance object actually access methods from the memory's Text/Method Segment in Java/Objective C?
据我了解(如有错误请指正),classes中的方法存储在C/Objective C内存的Code/Text段中。在Java中,方法存放在Method Area(相当于Code/Test Segment)。方法可以在编译时分配。我还相信每个对象,无论是 class 还是实例,都不会每次都用方法代码实例化。相反,方法只在 Code/Text 段中创建一次。然后位于堆段中的对象实例必须以某种方式 access/relate 这些方法。
1) 对象是否将方法的内存地址存储在其数据中?
2) 继承呢,对象是否以某种方式(通过"extends"等关键字)也存储了它们的superclass'方法的内存地址?
一般情况下,程序的代码都存放在代码段中,代码段又称为文本段。
有关不同细分市场的更多信息:
http://www.beingdeveloper.com/memory-layout-of-a-program/
基本上Code Segment有一个字段叫做“Offset”,这是指令可用的偏移地址。
例如,假设程序(二进制)加载到内存位置 0x802...
代码段将包含如下条目:
Offset Info Type Sym.Value Sym. Name
0000002d 00000501 R_386_32 00000000 .rodata
00000032 00000a02 R_386_PC32 00000000 printf
00000044 00000501 R_386_32 00000000 .rodata
00000049 00000a02 R_386_PC32 00000000 printf
加载代码的实际内存位置为:偏移+程序(二进制)加载位置。
详细解释:
问题 1 和问题 2 都试图为我指明最初的方向:class/instance 对象如何实际访问 [=24= 中内存的 Text/Method 段中的方法] C?
不幸的是,这两个问题实际上都走错了方向。这是我现在知道的:
a) 对象只是组合在一起的一组变量(属性)。如果分解成多个部分,对象只是原始变量的集合,它们以特定方式组合在一起(因此,数组样式或自定义 class 样式)。他们绝不会携带有关其方法的任何信息。大多数基于 class 的语言都是如此,例如 Java、Objective-C 或 Swift。但是,像Javascript这样的基于原型的语言,情况就大不一样了。
b) 方法实际上是一个独立于对象的实体。方法和函数一样,驻留在代码区中,只是二进制指令块。每当你调用一个方法时,你实际上是通过该方法的一个类似指针的内存地址来访问二进制指令块。此内存地址通过 function/method 标识符(名称)公开。所有方法就像函数一样,它们中的大多数实际上与全局函数共享相同的作用域。每个 function/method 名称都是唯一的(对编译器而言)并代表一个非常具体的内存地址。
因此,当您通过调用其名称来调用方法时,程序可以访问由函数标识符表示的特定位置。因此,函数只在代码区创建一次。与常规函数不同,方法必须需要特定 class 的实例才能工作。这基本上就是方法的全部要点——一个专门的函数,它需要来自对象的一组特定数据来执行专门的任务。因此,无论何时使用一个方法,都需要一个对象实例来伴随它。编译器只是帮助你自动将对象的指针作为参数传递给特定class的方法,并存储在"self"或"this"等局部变量中。换句话说,对象与其方法之间唯一的link是编译器自动创建一个对象指针作为方法的隐藏参数;并要求您实例化现有对象以实现该隐藏参数并允许调用这些方法。
据我了解(如有错误请指正),classes中的方法存储在C/Objective C内存的Code/Text段中。在Java中,方法存放在Method Area(相当于Code/Test Segment)。方法可以在编译时分配。我还相信每个对象,无论是 class 还是实例,都不会每次都用方法代码实例化。相反,方法只在 Code/Text 段中创建一次。然后位于堆段中的对象实例必须以某种方式 access/relate 这些方法。
1) 对象是否将方法的内存地址存储在其数据中?
2) 继承呢,对象是否以某种方式(通过"extends"等关键字)也存储了它们的superclass'方法的内存地址?
一般情况下,程序的代码都存放在代码段中,代码段又称为文本段。 有关不同细分市场的更多信息:
http://www.beingdeveloper.com/memory-layout-of-a-program/
基本上Code Segment有一个字段叫做“Offset”,这是指令可用的偏移地址。
例如,假设程序(二进制)加载到内存位置 0x802...
代码段将包含如下条目:
Offset Info Type Sym.Value Sym. Name
0000002d 00000501 R_386_32 00000000 .rodata
00000032 00000a02 R_386_PC32 00000000 printf
00000044 00000501 R_386_32 00000000 .rodata
00000049 00000a02 R_386_PC32 00000000 printf
加载代码的实际内存位置为:偏移+程序(二进制)加载位置。
详细解释:
问题 1 和问题 2 都试图为我指明最初的方向:class/instance 对象如何实际访问 [=24= 中内存的 Text/Method 段中的方法] C?
不幸的是,这两个问题实际上都走错了方向。这是我现在知道的:
a) 对象只是组合在一起的一组变量(属性)。如果分解成多个部分,对象只是原始变量的集合,它们以特定方式组合在一起(因此,数组样式或自定义 class 样式)。他们绝不会携带有关其方法的任何信息。大多数基于 class 的语言都是如此,例如 Java、Objective-C 或 Swift。但是,像Javascript这样的基于原型的语言,情况就大不一样了。
b) 方法实际上是一个独立于对象的实体。方法和函数一样,驻留在代码区中,只是二进制指令块。每当你调用一个方法时,你实际上是通过该方法的一个类似指针的内存地址来访问二进制指令块。此内存地址通过 function/method 标识符(名称)公开。所有方法就像函数一样,它们中的大多数实际上与全局函数共享相同的作用域。每个 function/method 名称都是唯一的(对编译器而言)并代表一个非常具体的内存地址。
因此,当您通过调用其名称来调用方法时,程序可以访问由函数标识符表示的特定位置。因此,函数只在代码区创建一次。与常规函数不同,方法必须需要特定 class 的实例才能工作。这基本上就是方法的全部要点——一个专门的函数,它需要来自对象的一组特定数据来执行专门的任务。因此,无论何时使用一个方法,都需要一个对象实例来伴随它。编译器只是帮助你自动将对象的指针作为参数传递给特定class的方法,并存储在"self"或"this"等局部变量中。换句话说,对象与其方法之间唯一的link是编译器自动创建一个对象指针作为方法的隐藏参数;并要求您实例化现有对象以实现该隐藏参数并允许调用这些方法。