How Are Objects Stored in RAM?

Page 2 - Seeking answers? Join the AnandTech community: where nearly half-a-million members share solutions and discuss the latest tech.

Merad

Platinum Member
May 31, 2010
2,586
19
81
I'm pretty sure there is no 1-byte lower limit for classes. You can have a zero size object that is nothing more than static maps to functions. I do it all the time.

This is incorrect, at least in C++. Each object must have a unique address, therefore no class may have a size of 0. If you take your class that only holds static functions and instantiate an instance of it, you'll find that it's size is 1 byte.

I don't remember for sure but I believe that Java has the concept of "static classes" which simply can't be instantiated.
 

Cogman

Lifer
Sep 19, 2000
10,286
147
106
This is incorrect, at least in C++. Each object must have a unique address, therefore no class may have a size of 0. If you take your class that only holds static functions and instantiate an instance of it, you'll find that it's size is 1 byte.

I don't remember for sure but I believe that Java has the concept of "static classes" which simply can't be instantiated.

It is more you can have a class with a private constructor which makes it uninstantiatable. Same thing you can do with C++.
 

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
I don't remember for sure but I believe that Java has the concept of "static classes" which simply can't be instantiated.

In Java, abstract classes and interfaces can not be instantiated. They serve merely as templates for "concrete" classes to extend or implement.

It is more you can have a class with a private constructor which makes it uninstantiatable. Same thing you can do with C++.

Yes, but only outside that class. Within that class, you can call the private constructor and instantiate an object.

Then, you can sneakily use a non-private static method to "cheat" and get a hold of an instance of the class whose constructor is private outside of that class.

Example:

class Test{

int i;

private Test(int i){

this.i = i;

}

static Test method(int i){

Test test = new Test(i);

return test;

}

}

class Demo{

public static void main(String[] z){

System.out.println( Test.method(0).i );

}

}


The difference between the situation you mentioned and abstract classes and interfaces is that abstract classes and interfaces can not be instantiated ever from any place.

That's just Java though. I don't know about anything else.
 
Last edited:

Fox5

Diamond Member
Jan 31, 2005
5,957
7
81
Memory is essentially a large ticker tape machine (a Turing machine). You have a contiguous linear array, and you assign addresses from 0 to max_address.

Your primitive data types will merely exist at some point in ram, and the code knows what's there. There's no type information, other than the code says "load int from address 0x2000".
However, something like a string will typically be referenced by pointers. So a string exists as a null terminated array of chars in memory, but is referenced by a pointer, which is a memory address. So the code would say "load string pointer from address 0x2000" and then treat that variable as a special type of variable. The string pointer keeps getting incremented to get the next character in the string.
That gives you a hint about how an object works, which is essentially the same.

The next step up is a C struct, which is similar to an array, except you don't have evenly spaced offsets between values, and values can be of different types. Once again, the spacing and typing is only defined in the code and has no actual meaning independent of it. A C struct can contain pointers to other things, which is getting pretty close to an object.

Now the primary difference for an object in Java (and probably C++ as well) is that there are fields in its Object struct that give some idea of type information. So in Java, since everything is derived from the Object class, everything has a "header" that consists of the same object fields at the same spacing. These fields can tell you things like "instanceof" and name. Then any Object extending Object can have an arbitrary number of additional things in it beyond the Object "header". The ability of an Object to tell you about itself is called "reflection" and the ability to extend an object is called "inheritance", and you can look up both things on Wikipedia.
 

Merad

Platinum Member
May 31, 2010
2,586
19
81
Classes in C++ without virtual functions are laid out identical to C structs. Classes with virtual functions begin with a vtable which typically includes a pointer to the class type information (if RTTI is enabled) and pointers to it's virtual functions.
 

Cogman

Lifer
Sep 19, 2000
10,286
147
106
In Java, abstract classes and interfaces can not be instantiated. They serve merely as templates for "concrete" classes to extend or implement.



Yes, but only outside that class. Within that class, you can call the private constructor and instantiate an object.

Then, you can sneakily use a non-private static method to "cheat" and get a hold of an instance of the class whose constructor is private outside of that class.

Example:

class Test{

int i;

private Test(int i){

this.i = i;

}

static Test method(int i){

Test test = new Test(i);

return test;

}

}

class Demo{

public static void main(String[] z){

System.out.println( Test.method(0).i );

}

}


The difference between the situation you mentioned and abstract classes and interfaces is that abstract classes and interfaces can not be instantiated ever from any place.

That's just Java though. I don't know about anything else.

I don't like the idea of using an abstract class or interface as a static method holder. Abstract classes and interfaces connotate to anyone that stumbles over them that they should extend them. Which isn't what you want with a bag of functions.

For my bags of functions, I like something that looks like this

Code:
public final class BagOFunctions
{
	private BagOFunctions(){}
	
	public static void doThing(int onThing)
	{
	}
}

It lets every developer that stumbles across this code know that the class should not be instantiated, it can't be extended, and the only real functionality you can gain is from using static methods.

Yes, you could technically instantiate it in one of the methods, but you would pretty much have to ignore everything about the surrounding pattern of the class to do that (IE, you are a terrible person and a terrible developer).
 

Cogman

Lifer
Sep 19, 2000
10,286
147
106
Classes in C++ without virtual functions are laid out identical to C structs. Classes with virtual functions begin with a vtable which typically includes a pointer to the class type information (if RTTI is enabled) and pointers to it's virtual functions.

Post C++11 compilers are getting smarter about this, btw. If you aggressively declare classes and methods as "final" it will so some hocus pocus to eliminate the vtable in many circumstances.
 

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
I don't like the idea of using an abstract class or interface as a static method holder. Abstract classes and interfaces connotate to anyone that stumbles over them that they should extend them. Which isn't what you want with a bag of functions.

For my bags of functions, I like something that looks like this

Code:
public final class BagOFunctions
{
	private BagOFunctions(){}
	
	public static void doThing(int onThing)
	{
	}
}

It lets every developer that stumbles across this code know that the class should not be instantiated, it can't be extended, and the only real functionality you can gain is from using static methods.

Oh, I see. Like a utility class. What about using an enum with no fields?

Example:

Code:
enum Demo{;

static int method(){

return 2;

}

//other static methods

public static void main(String[] z){

System.out.println( method() );

}

}

It meets all the criteria you care about. It can't be instantiated or extended.

Yes, you could technically instantiate it in one of the methods, but you would pretty much have to ignore everything about the surrounding pattern of the class to do that (IE, you are a terrible person and a terrible developer).

Ouch.
 

Cogman

Lifer
Sep 19, 2000
10,286
147
106
Oh, I see. Like a utility class. What about using an enum with no fields?

Example:

Code:
enum Demo{;

static int method(){

return 2;

}

//other static methods

public static void main(String[] z){

System.out.println( method() );

}

}

It meets all the criteria you care about. It can't be instantiated or extended.



Ouch.

An enum would work, but it is bending the definition of enum in an unnatural way. Like I said, Having a private constructor with static methods very clearly signals intent. On top of that, it is a fairly common pattern you'll find in most places.

There is no good reason to depart from a common and clear pattern just because you are afraid that someone might modify the utility class you just created to start instantiating it.
 

Schmide

Diamond Member
Mar 7, 2002
5,798
1,125
126
This is incorrect, at least in C++. Each object must have a unique address, therefore no class may have a size of 0. If you take your class that only holds static functions and instantiate an instance of it, you'll find that it's size is 1 byte.

Maybe in debug mode, but in release the class will be declared dead and useless and never initiated. The functions that pass through it will be mapped to their static address.

Sizeof will never return 0 but that doesn't mean there is always a runtime byte.
 
Last edited:

Merad

Platinum Member
May 31, 2010
2,586
19
81
Maybe in debug mode, but in release the class will be declared dead and useless and never initiated. The functions that pass through the it will be mapped to their static address.

Sizeof will never return 0 but that doesn't mean there is always a runtime byte.

That's true, but the size of the class is still 1 byte whether the optimizer removes it or not.