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.