• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

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.
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.
 
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++.
 
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:
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.
 
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.
 
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).
 
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.
 
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.
 
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.
 
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:
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.
 
Back
Top