Size of A Class (object) in .NET - c#

How to determine if a Class in .NET is big or small? Is it measured on how many it's attributes or fields, datatype of its attributes/fields? or return type of methods? parameters of it's methods? access modifier of its methods, virtual methods? thanks..
class A
{
string x { get; set; }
}
class B
{
int x { get; set; }
}
in this example if I instantiate class A and B like this
A objA = new A();
B objB = new B();
Is class objA the bigger one because it holds an String property and objB holds only an Int? although I didn't set any value to it's property. thanks
EDIT: Just to clarify my question
suppose i have a class
public class Member
{
public string MainEmpId { get; set; }
public string EmpId { get; set; }
}
and another class
public class User
{
public string AccessLevel { get; set; }
public string DateActivated { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Mi { get; set; }
public string Password { get; set; }
public string UserId { get; set; }
public string UserName { get; set; }
public string Active { get; set; }
public string ProviderName { get; set; }
public string ContactPerson { get; set; }
public string Relation { get; set; }
public string Landline { get; set; }
public string MobileNo { get; set; }
public string Complaint { get; set; }
public string Remarks { get; set; }
public string Reason { get; set; }
public string RoomType { get; set; }
}
if I instantiate it like this
Member A = new Member();
User B = new User()
is the object A larger than object B?
I know it's an odd question but I believe every intantiation of an object eats memory space..

The size of a class instance is determined by:
The amount of data actually stored in the instance
The padding needed between the values
Some extra internal data used by the memory management
So, typically a class containing a string property needs (on a 32 bit system):
8 bytes for internal data
4 bytes for the string reference
4 bytes of unused space (to get to the minimum 16 bytes that the memory manager can handle)
And typically a class containing an integer property needs:
8 bytes for internal data
4 bytes for the integer value
4 bytes of unused space (to get to the minimum 16 bytes that the memory manager can handle)
As you see, the string and integer properties take up the same space in the class, so in your first example they will use the same amount of memory.
The value of the string property is of course a different matter, as it might point to a string object on the heap, but that is a separate object and not part of the class pointing to it.
For more complicated classes, padding comes into play. A class containing a boolean and a string property would for example use:
8 bytes for internal data
1 byte for the boolean value
3 bytes of padding to get on an even 4-byte boundary
4 bytes for the string reference
Note that these are examples of memory layouts for classes. The exact layout varies depending on the version of the framework, the implementation of the CLR, and whether it's a 32-bit or 64-bit application. As a program can be run on either a 32-bit or 64-bit system, the memory layout is not even known to the compiler, it's decided when the code is JIT:ed before execution.

In general, a class is larger when it has many instance (non-static) fields, regardless of their value; classes have a memory minimum of 12 bytes and fields with reference types are 4 bytes on 32-bit systems and 8 bytes on 64-bit systems. Other fields may be laid out with padding to word boundaries, such that a class with four byte fields actually may occupy four times 4 bytes in memory. But this all depends on the runtime.
Don't forget about the fields that may be hidden in, for example, your automatic property declarations. Since they are backed by a field internally, they'll add to the size of the class:
public string MyProperty
{ get; set; }
Note that the following property has no influence on the class size because it isn't backed by a field:
public bool IsValid
{ get { return true; } }
To get an idea of the in-memory size of a class or struct instance: apply the [StructLayout(LayoutKind.Sequential)] attribute on the class and call Marshal.SizeOf() on the type or instance.
[StructLayout(LayoutKind.Sequential)]
public class MyClass
{
public int myField0;
public int myField1;
}
int sizeInBytes = Marshal.SizeOf(typeof(MyClass));
However, because the runtime can layout the class in memory any way it wishes, the actual memory used by an instance may vary unless you apply the StructLayoutAttribute.

While the following article is old (.NET 1.1), the concepts explain clearly what the CLR is doing to allocate memory for objects instantiated in your application; which heaps are they placed in, where their object reference pointers are addressing, etc.
Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects

You can also check: how-much-memory-instance-of-my-class-uses.
There is easy way to test size of object after constructor is called.

There's a project on github called dotnetex that uses some magic and shows the size of a class or object.
Usage is simple:
GCex.SizeOf<Object>(); // size of the type
GCEx.SizeOf(someObject); // size of the object;
Under the hood it uses some magic.
To count size of a type it casts pointer of method table to internal MethodTableInfo struct and uses it's Size property like this:
public static unsafe Int32 SizeOf<T>()
{
return ((MethodTableInfo *)(typeof(T).TypeHandle.Value.ToPointer()))->Size;
}
To count size of an object it uses true dark magic that quite hard to get :) Take a look at the code.

When one says class size, I would assume that it means how many members the class has, and how complex the class is.
However, your question is the size of the memory required when we are creating instance of class. We cannot be so sure about exact size, because .Net framework preserves and keeps the underlying memory management away from us (which is a good thing). Even we have the correct size now, the value might be correct forever. Anyway, we can be sure that the following will take some space in the memory:
Instance variable.
Automatic property.
So that makes sense to say that User class will take more memory than Member class does.

Related

memory allocation of blank class in c# [duplicate]

How to determine if a Class in .NET is big or small? Is it measured on how many it's attributes or fields, datatype of its attributes/fields? or return type of methods? parameters of it's methods? access modifier of its methods, virtual methods? thanks..
class A
{
string x { get; set; }
}
class B
{
int x { get; set; }
}
in this example if I instantiate class A and B like this
A objA = new A();
B objB = new B();
Is class objA the bigger one because it holds an String property and objB holds only an Int? although I didn't set any value to it's property. thanks
EDIT: Just to clarify my question
suppose i have a class
public class Member
{
public string MainEmpId { get; set; }
public string EmpId { get; set; }
}
and another class
public class User
{
public string AccessLevel { get; set; }
public string DateActivated { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Mi { get; set; }
public string Password { get; set; }
public string UserId { get; set; }
public string UserName { get; set; }
public string Active { get; set; }
public string ProviderName { get; set; }
public string ContactPerson { get; set; }
public string Relation { get; set; }
public string Landline { get; set; }
public string MobileNo { get; set; }
public string Complaint { get; set; }
public string Remarks { get; set; }
public string Reason { get; set; }
public string RoomType { get; set; }
}
if I instantiate it like this
Member A = new Member();
User B = new User()
is the object A larger than object B?
I know it's an odd question but I believe every intantiation of an object eats memory space..
The size of a class instance is determined by:
The amount of data actually stored in the instance
The padding needed between the values
Some extra internal data used by the memory management
So, typically a class containing a string property needs (on a 32 bit system):
8 bytes for internal data
4 bytes for the string reference
4 bytes of unused space (to get to the minimum 16 bytes that the memory manager can handle)
And typically a class containing an integer property needs:
8 bytes for internal data
4 bytes for the integer value
4 bytes of unused space (to get to the minimum 16 bytes that the memory manager can handle)
As you see, the string and integer properties take up the same space in the class, so in your first example they will use the same amount of memory.
The value of the string property is of course a different matter, as it might point to a string object on the heap, but that is a separate object and not part of the class pointing to it.
For more complicated classes, padding comes into play. A class containing a boolean and a string property would for example use:
8 bytes for internal data
1 byte for the boolean value
3 bytes of padding to get on an even 4-byte boundary
4 bytes for the string reference
Note that these are examples of memory layouts for classes. The exact layout varies depending on the version of the framework, the implementation of the CLR, and whether it's a 32-bit or 64-bit application. As a program can be run on either a 32-bit or 64-bit system, the memory layout is not even known to the compiler, it's decided when the code is JIT:ed before execution.
In general, a class is larger when it has many instance (non-static) fields, regardless of their value; classes have a memory minimum of 12 bytes and fields with reference types are 4 bytes on 32-bit systems and 8 bytes on 64-bit systems. Other fields may be laid out with padding to word boundaries, such that a class with four byte fields actually may occupy four times 4 bytes in memory. But this all depends on the runtime.
Don't forget about the fields that may be hidden in, for example, your automatic property declarations. Since they are backed by a field internally, they'll add to the size of the class:
public string MyProperty
{ get; set; }
Note that the following property has no influence on the class size because it isn't backed by a field:
public bool IsValid
{ get { return true; } }
To get an idea of the in-memory size of a class or struct instance: apply the [StructLayout(LayoutKind.Sequential)] attribute on the class and call Marshal.SizeOf() on the type or instance.
[StructLayout(LayoutKind.Sequential)]
public class MyClass
{
public int myField0;
public int myField1;
}
int sizeInBytes = Marshal.SizeOf(typeof(MyClass));
However, because the runtime can layout the class in memory any way it wishes, the actual memory used by an instance may vary unless you apply the StructLayoutAttribute.
While the following article is old (.NET 1.1), the concepts explain clearly what the CLR is doing to allocate memory for objects instantiated in your application; which heaps are they placed in, where their object reference pointers are addressing, etc.
Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects
You can also check: how-much-memory-instance-of-my-class-uses.
There is easy way to test size of object after constructor is called.
There's a project on github called dotnetex that uses some magic and shows the size of a class or object.
Usage is simple:
GCex.SizeOf<Object>(); // size of the type
GCEx.SizeOf(someObject); // size of the object;
Under the hood it uses some magic.
To count size of a type it casts pointer of method table to internal MethodTableInfo struct and uses it's Size property like this:
public static unsafe Int32 SizeOf<T>()
{
return ((MethodTableInfo *)(typeof(T).TypeHandle.Value.ToPointer()))->Size;
}
To count size of an object it uses true dark magic that quite hard to get :) Take a look at the code.
When one says class size, I would assume that it means how many members the class has, and how complex the class is.
However, your question is the size of the memory required when we are creating instance of class. We cannot be so sure about exact size, because .Net framework preserves and keeps the underlying memory management away from us (which is a good thing). Even we have the correct size now, the value might be correct forever. Anyway, we can be sure that the following will take some space in the memory:
Instance variable.
Automatic property.
So that makes sense to say that User class will take more memory than Member class does.

Protobuf.net - all fields of a class required to be serialized

Here is an example class provided by Marc Gravel in his introduction on how to use Protobuf.net:
[ProtoContract]
class Person {
[ProtoMember(1)]
public int Id {get;set;}
[ProtoMember(2)]
public string Name {get;set;}
[ProtoMember(3)]
public Address Address {get;set;}
}
[ProtoContract]
class Address {
[ProtoMember(1)]
public string Line1 {get;set;}
[ProtoMember(2)]
public string Line2 {get;set;}
}
I have some questions, which I could not find the answers for after searching the web:
If on day 1, I know that I don't need the name property [ProtoMember(2)], then if I omit the [ProtoMember(2)] attribute, will Protobut.net ignore that property and not include it in the output serialized data? If true, then when the data is deserialized on the other end - what is Name initialized to - null?
Lets say that all 3 properties are initially serialized as shown above. If in the future, it turns out that the name property [ProtoMember(2)] is no longer required, can the [ProtoMember(2)] attribute be safely omitted so that only the first and third property are serialized? If true, would it be OK to simply leave the attribute numbers as shown (i.e. 1 & 3)? Any caveats if this is the case?
If it is OK to omit a serialization attribute for a property in a class, then what happens if the class definition on the deserialization side is out of sync? For example, say that the deserialization class defines all 3 properties above, but the serialization code only defines 1 and 3? Likewise, if the deserialization code only expects to see properties 1 and 3, but the serialization code sends all 3, would that still work or will it generate an error?
correct; in terms of what it is initialized to - that's usually up to your type, so in this case (since your type doesn't initialize it), yes: null (note: there is also an option in which the constructor can be suppressed, in which case it would be null even if your class had a constructor / initializer)
yes, that's fine (and expected)
the addition and removal of properties is expected and normal, so the library forgives either; when unexpected fields are received, what happens next depends on whether your class implements IExtensible (often by subclassing Extensible) - if it does, the unexpected data is stored separately, so that it can still be queried manually, or (more common) "round tripped" (i.e. if you serialize it again, the extra data is persisted, even though you didn't expect it)
(yes I know you didn't ask a 4) - the library also supports "conditional serialization", where-by properties can be omitted based on conditions - for example public bool ShouldSerializeName() => Name != null && SomethingElse == 42;
Since others may want to know the answer to these questions, I decided to post the question and share my findings.
These questions are actually quite easy to solve with a test program:
class Program
{
static void Main(string[] args)
{
var person = new Person1
{
Id = 12345,
Name = "Fred",
Address = new Address
{
Line1 = "Flat 1",
Line2 = "The Meadows"
}
};
//
byte[] arr = Serialize(person);
Person2 newPerson = Deserialize(arr);
/*
using (var file = File.Create("person.bin"))
{
Serializer.Serialize(file, person);
}
//
Person newPerson;
using (var file = File.OpenRead("person.bin"))
{
newPerson = Serializer.Deserialize<Person>(file);
}
*/
}
public static byte[] Serialize(Person1 person)
{
byte[] result;
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, person);
result = stream.ToArray();
}
return result;
}
public static Person2 Deserialize(byte[] tData)
{
using (var ms = new MemoryStream(tData))
{
return Serializer.Deserialize<Person2>(ms);
}
}
}
[ProtoContract]
class Person1
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
[ProtoMember(3)]
public Address Address { get; set; }
}
[ProtoContract]
class Address
{
[ProtoMember(1)]
public string Line1 { get; set; }
[ProtoMember(2)]
public string Line2 { get; set; }
}
[ProtoContract]
class Person2
{
[ProtoMember(1)]
public int Id { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
[ProtoMember(3)]
public Address Address { get; set; }
}
So, to try out if Protobuf.net will ignore the Name property when serializing, first run the code in debug to see the total number of bytes with all 3 properties serialized. This can be done by setting a breakpoint at the Serialize(person) line and examining the size of arr.
Then, remove the [ProtoMember(2)] attribute from the Name property of the Person1 class. Running the code in debug shows that it leaves it out because the number of bytes is 6 less than before. When the object is then deserialized back to an object of Person2, it then shows that the Name property is initialized to null.
After replacing the [ProtoMember(2)] attribute for the Name property in the Person1 class, remove this same attribute for the Person2 class. After debugging through the code, it shows that after the Deserialize call, the Person2.Name property is set to null.
So, it looks like Protobuf.net was well designed to be quite flexible, efficient, and in some ways is backwards compatible in that it supports removing of obsolete properties.

How to pass data between function calls

We can pass data between functions by using class objects. Like i have class
public class AddsBean
{
public long addId{get;set;}
public int bid { get; set; }
public long pointsAlloted { get; set; }
public string userId { get; set; }
public enum isApproved { YES, NO };
public DateTime approveDate { get; set; }
public string title { get; set; }
public string description { get; set; }
public string Link { get; set; }
public DateTime dateAdded { get; set; }
}
We can call function like public List<AddsBean> getAdds(string Id). This approach is good when you need all the variables of class. But what if you need only 2 or 3 variables of class?
Passing object of class is not good because it will be wastage of memory. Another possible solution is to make different classes of lesser variables but that is not practical.
What should we do that will best possible solution to fulfill motive and best according to performance also?
In Java - "References to objects are passed by value".. So, you dont pass the entire object, you just pass the reference to the object to the called function.
EG:
class A{
int i;
int j;
double k;
}
class B{
public static void someFunc(A a) // here 'a' is a reference to an object, we dont pass the object.
{
// some code
}
public static void main(String[] args){
A a = new A();
B.someFunc(a); // reference is being passed by value
}
}
first of all, as Java is pass by value and references typed, there is no need to worry about the memory wastage.
next, as you have mentioned, it is not good to pass all the object if you do not need them all, in some situation, it's true. as you need to protect your data in instance, thus you can use different granularity of class, for instance:
class A
{id, name}
class B extends A
{password,birthday}
by refer to different class you can control the granularity yourself, and provide different client with different scope of data.
But in some condition, you need to use a instance to store all data in the whole application, like configure data in hadoop, or some other configuration related instance.
Try to choose the most suitable scope!
If you're sure that this is the source of problems and you don't want to define a new class with a subset of the properties, .NET provides the Tuple class for grouping a small number of related fields. For example, a Tuple<int, int, string> contains two integers and a string, in that order.
public Tuple<string, long, DateTime> GetPointsData()
{
AddsBean bean = ... // Get your AddsBean somehow
return Tuple.Create<string, long, DateTime>(bean.userId, bean.pointsAlloted, bean.approveDate);
}
Once this method goes out of scope, there is no longer a live reference to the object bean referred to and will be collected by the garbage collector at some point in the future.
That said, unless you're sure that instances of the AddsBean class are having a noticeable negative effect on the performance of your app, you should not worry about it. The performance of your application is probably affected far more by other operations. Returning a reference type (a type defined with class instead of struct) only passes a reference to the object, not the data of the object itself.

Struct with auto-implemented properties and constructor initializer

Recently a compiler warning and (very useful) hint prompted me to write the code below.
I had no idea you could do this, but it is perfectly legal, and also convenient in that I can declare a managed struct with public properties similar to public fields of an unmanaged struct, and also initialize it with an object instead of having to pass all the fields as parameters.
What confuses me is that this appears to call the explicit parameterless constructor, which would of course be illegal for this struct.
What's going on here, and has this syntax always been supported?
internal struct IconEntry
{
public byte Width { get; set; }
public byte Height { get; set; }
public byte ColorCount { get; set; }
public byte Reserved { get; set; }
public short Planes { get; set; }
public short BitCount { get; set; }
public int BytesInRes { get; set; }
public int ImageOffset { get; set; }
public IconEntry(BinaryReader reader)
: this()
{
Width = reader.ReadByte();
Height = reader.ReadByte();
ColorCount = reader.ReadByte();
Reserved = reader.ReadByte();
Planes = reader.ReadInt16();
BitCount = reader.ReadInt16();
BytesInRes = reader.ReadInt32();
ImageOffset = reader.ReadInt32();
}
}
A struct always has a public parameterless constructor which can't be overriden: http://msdn.microsoft.com/en-us/library/aa288208%28v=vs.71%29.aspx
This means that a user still would be able to create an instance of this struct that is not initialized according to your logic but with default values for all properties:
var s = new IconEntry();
All structs have a parameterless constructor - it's just implicit (e.g. it always exists with a default routine - one that sets all values to 0) - you just can't have an explicit one (e.g. one that you define yourself in code).
Is there any reason you're exposing properties rather than fields for your struct? If the semantics of your data type imply that
The entire state of an instance will be fully defined by the values exposed by some public members, such that two instances for whom all those report or contain identical values will be considered identical.
Instances of the struct with any combination of values for the aforementioned members may be created easily, given the desired values in question.
that sounds like a perfect fit for a PODS (Plain Old Data Struct). Exposed fields are more efficient and less quirky than struct properties. Given that all struct types always expose all fields for mutation or capture by struct assignment, the encapsulation offered by struct properties is of extremely limited value.
The way you have your constructor written, your struct will have all fields set to all-bits-zero, and then be passed repeatedly to methods which will update one field at a time with the desired value. The fact that the struct is specified as initialized to all-bits-zero by the this will make the compiler happy, but using many individual properties to set up fields piecemeal is inefficient.
Incidentally, even better than a constructor in many cases would be a static method which simply takes your struct as a ref parameter. In many cases, using a constructor with a struct will result in an unnecessary copy operation which could be avoided by using a static method with a ref parameter.
Since structs are value types, it's data members should be initialized if you are explicitly invoke the constructor. And mention "this()" to intimate compiler to complete the assignment of auto implemented properties if anything you mentioned.
struct Student
{
string _sname;
public int ID
{
get; set;
}
internal Student(string sname):this()
{
_sname = sname;
}
internal void PrintDetails()
{
Console.WriteLine("ID : {0} Name: {1}", ID, _sname);
}
}
Main method:
class Program
{
static void Main()
{
Student st = new Student("John")
{
ID=101
};
st.PrintDetails();
}
}
Output:
ID : 101 Name: John
If you are not mention "this()", compiler forcefully ask you to complete the full assignment of ID property.
If you are not explicitly invoke the constructor, compiler implicitly set default values for the struct data members.

Is this too much data that should be used in a Struct?

public struct Cache {
public int babyGangters { get; set; }
public int punks { get; set; }
public int ogs { get; set; }
public int mercs { get; set; }
public int hsPushers { get; set; }
public int collegeDealers { get; set; }
public int drugLords { get; set; }
public int streetHoes { get; set; }
public int webcamGrls { get; set; }
public int escort { get; set; }
public int turns { get; set; }
public int cash { get; set; }
public int bank { get; set; }
public int drugs { get; set; }
public int totalValue { get; set; }
public int attackIns { get; set; }
public int attackOuts { get; set; }
public int status { get; set; }
public int location { get; set; }
}
That's not only too big by most guidelines, but it's also mutable. That's a much bigger red flag in my view.
Mutable structs can cause unexpected behaviour in many situations. Just say "no".
Why do you want this to be a struct in the first place? And does it really need to be mutable?
The rule of thumb is that a struct should not be bigger than 16 bytes (according to the Framework Design Guidelines). Your struct is 76 bytes (= 19 * 4), so it is pretty big. However, you will have to measure the performance. Big structs can be beneficial for some applications.
The Framework Design Guidelines state:
Avoid defining a struct unless the
type [...] an instance size under 16
bytes.
One of the annotations from Jeffrey Richterto this guidlines state:
Value types can be more than 16
bytes if you don't intend to pass them
to other methods or copy them to and
from a collection class (like an
array).
There is no hard and fast rule as to what constitutes a struct that is too big. There several guidelines available. Most notably the .Net Design Guidelines which recomend a struct not exceed 16 bytes in size.
However these are just guidelines. Whether or not a struct is too big depends highly on the context in which it is used. For example if the struct is created once and only passed by ref / out to all functions then it's size is much less important than one which is frequently passed by value.
In .Net, use classes unless you have a good reason not to. "I want it on the stack" with no other qualifiers is not usually a good reason.
http://www.codeproject.com/KB/cs/structs_in_csharp.aspx
struct improve memory e speed performance, but must be small, in this case utilize a class.
If the item is a struct, any attempt to change a field will only change the field in that particular struct instance. In some circumstances, .net will create temporary struct instances, and if you're not careful your attempts to change a field will simply change the field in that temp instance, rather than in anything more persistent. That is the 'gotcha' that Jon Skeet is warning you about.
On the other hand, a struct variable does have the advantage that value types within it can only be changed if that variable itself is written. The risk that an attempt to change a temporary struct might fail (described above) should be weighed against the risk that an two class variables might get aliased to the same object when they should in reality point to two different objects which happen to have the same property values. If that happens, a change to one variable might accidentally change the other.
One way to think of a struct is like a class which gets cloned any time it gets passed around, but with a cloning operation that's cheaper than that of a class. If 10%-50% or more of the uses of a class would require that it be cloned, you're probably better off with a struct. If you would mostly be using it without cloning it, use a class.
BTW, I wouldn't bother with settable properties; if something is settable, just make the field public. Since structs can't be inherited, there's no loss of generality.
It's impossible to answer that because this depends on your application and usage.
However, yes, with this much data you should really think about creating a class instead of a struct.
You could also ask yourself if you can logically group some of those fields into structs or classes.
The decision as to whether or not to use a struct should be based more on how you want to use it than on how large it is. You should ask yourself if there's any compelling benefit to making this a struct instead of a class. Do you really need value type semantics? Do you need to allocate tens of millions of these things and can't pay the allocation overhead (12 or 24 bytes, depending on the platform) if they're classes? I suspect that the answer to both of those questions is "No", so it's likely that you want to make this thing a class rather than a struct.

Categories

Resources