在Java中,一个类的所有成员是否都存储在连续的内存中?

huangapple go评论72阅读模式
英文:

In Java, are all members of a class stored in contiguous memory?

问题

在搜索是否已经有人回答这个问题时,我找到了https://stackoverflow.com/questions/15430848/are-class-members-guaranteed-to-be-contiguous-in-memory,但那是关于C++而不是Java的。

为了提供背景,我有Go的背景,正在学习Java。我知道在Go中,我可以像这样使用指针来编写结构体:

type myStruct struct {
    firstMember  *string
    secondMember *int
}

但是在详细学习Go时,我经常读到,除非你真的需要它们是指针,否则这是一个不好的主意,因为它意味着每个成员的值可以分散在动态内存的任何位置,这会降低性能,因为它无法充分利用CPU中的空间局部性。

相反,通常建议以不使用指针的方式编写结构体:

type myStruct struct {
	firstMember  string
	secondMember int
}

在学习如何有效地编写Java时,我想知道在使用Java时是否有类似的工具。由于我不能使用指针(因为每个类型为类的变量都是对该类的引用,实际上是一个指针),我只能使用Stringint来编写类:

class MyClass {
    String firstMember;
    int secondMember;
}

意识到这是编写我的数据结构的唯一方法,我提出了这个问题。

英文:

While searching whether this was already answered, I found https://stackoverflow.com/questions/15430848/are-class-members-guaranteed-to-be-contiguous-in-memory, but that deals with C++, not Java.

To provide context, I have a background in Go and I'm learning Java. I know that with Go, I can write a struct using pointers like this:

type myStruct struct {
    firstMember  *string
    secondMember *int
}

But when studying Go in detail, I often read about this being a bad idea unless you really need them to be pointers, because it means the values for each member can be spread anywhere across dynamic memory, hurting performance because it's less able to take advantage of spatial locality in the CPU.

Instead, it's often recommended to write the struct this way, without using pointers:

type myStruct struct {
	firstMember  string
	secondMember int
}

As I learn how to effectively write Java, I'm curious if I have this same tool in my toolset when working with Java. Since I don't have the ability to use pointers (because every variable whose type is a class is a reference to that class, effectively a pointer), I can only write the class using String and int:

class MyClass {
    String firstMember;
    int secondMember;
}

Realizing that this was the only way to write a class for my data structure led me to the question posed.

答案1

得分: 1

但是在详细学习Go语言时,我经常读到,除非你真的需要将它们作为指针,否则这是一个不好的主意,因为这意味着每个成员的值可以分散在动态内存的任何位置,这会降低性能,因为它无法充分利用CPU的空间局部性。

在Java中,你没有选择。

class MyClass {
    String firstMember;
    int secondMember;
}

String类型的成员是引用(实际上是指针)。int类型的成员是原始值(不是指针)。

Java世界分为原始值和对象(某个类的实例、数组等等)。前者的变量不是引用,后者的变量是引用。

Java语言规范根本不涉及对象布局;这不是该语言中出现的概念。

JVM规范明确指出:

Java虚拟机不强制要求对象的任何特定内部结构。

实际上,你可能会猜测类实例的主体是一块连续的内存,但这仍然存在对齐、填充和成员排序的问题(我看不到保持源代码顺序的理由,而且有一些重新排序的理由)。

英文:

> But when studying Go in detail, I often read about this being a bad
> idea unless you really need them to be pointers, because it means the
> values for each member can be spread anywhere across dynamic memory,
> hurting performance because it's less able to take advantage of
> spatial locality in the CPU.

You have no choice in Java.

class MyClass {
    String firstMember;
    int secondMember;
}

The String-valued member is, and can only be, a reference (i.e., effectively a pointer). The int-valued member is a primitive value (i.e., not a pointer).

The Java world is divided into primitive values and objects (of some class, or arrays, and so on). Variables for the former types are not references, variables for the latter types are references.

The Java Language Specification does not talk about object layout at all; that's not a concept that appears in the language.

The JVM Specification specifically says

> The Java Virtual Machine does not mandate any particular internal
> structure for objects.

Pragmatically, you might guess that the body of a class instance is a single piece of memory, but that still leaves open the questions of alignment, padding, and ordering or members (no reason to keep source-code order that I can see, and some reasons to reorder).

huangapple
  • 本文由 发表于 2021年8月15日 01:45:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/68785707.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定