0

While searching whether this was already answered, I found 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.

Matt Welke
  • 1,441
  • 1
  • 15
  • 40
  • 5
    Please read: [Can I ask only one question per post?](https://meta.stackexchange.com/questions/222735/can-i-ask-only-one-question-per-post) --- "*Does this mean that the String member (and any members I have that are other classes) is always going to be a pointer when it runs in the JVM?*" - A reference, yes. --- "*And does that mean that I have no way of writing a data structure that is guaranteed to be stored in contiguous memory?* - Yes. --- "*Or, does Java a mechanism to enable this technique?*" - [Project Valhalla](https://openjdk.java.net/projects/valhalla/) does address those concerns. – Turing85 Aug 14 '21 at 17:48
  • 1
    Thanks for the link. I've cleaned up my question by removing all the extra questions so that the only remaining question is whether or not the members of the class are stored in contiguous memory. I appreciate you answering all those for me though. – Matt Welke Aug 14 '21 at 17:53
  • 6
    The Java spec provides *no guarantees whatsoever* about physical memory layout. – chrylis -cautiouslyoptimistic- Aug 14 '21 at 17:54
  • 1
    Yes. Members of a class are stored continuously in memory. But in the case of reference types it’s their _pointers_ that are stored; i.e. in your example `String`. This is relied upon by various `Unsafe` hacks. It’s not guaranteed however… – Boris the Spider Aug 14 '21 at 17:55
  • 4
    And in fact, the memory layout from one OS-specific JVM may be different for another – Hovercraft Full Of Eels Aug 14 '21 at 17:55
  • The great thing about the Java *virtual machine* is that you 100% **explicitly** cannot directly manipulate real memory. Although a `ByteBuffer` is like an exception I guess. – Elliott Frisch Aug 14 '21 at 17:59
  • 1
    @ElliottFrisch with Foreign Memory Access API from Java 14 onwards you can manipulate real memory – Panagiotis Bougioukos Aug 14 '21 at 18:17
  • @PanagiotisBougioukos The foreign-memory API is still being incubated in Java 17, not yet an official feature. Which means it won’t be an official feature until next year, 2022, at the earliest. See: [*JEP 412: Foreign Function & Memory API (Incubator)*](https://openjdk.java.net/jeps/412). – Basil Bourque Aug 14 '21 at 20:04
  • So far, a few contradictory answers have been provided via comments. The first is "The Java spec provides no guarantees whatsoever about physical memory layout." and the second is "Yes. Members of a class are stored continuously in memory.". If someone can verify which answer is correct, I can either mark it as correct (if they post it) or post it myself and then mark that as correct. – Matt Welke Aug 19 '21 at 00:15

1 Answers1

1

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).

passer-by
  • 1,103
  • 2
  • 4