9

In response to Aaronaught's response to the question at:

Can't I just use all static methods?

Isn't less memory used for a static method? I am under the impression that each object instance carries around its own executable version of a non-static member function.

Regardless of how much overhead is involved in calling a static method, regardless of poor OO design, and possible headaches down the road, doesn't it use less memory at runtime?

Here is an example:

I make a vector of zero-initialized objects. Each object contains one piece of data (a triangle consisting of nine double's). Each object is populated in sequence from data read from a .stl file. Only one static method is needed. Proper OO design dictates that a method dealing with the the data directly should be distributed to each object. Here is the standard OO solution:

foreach(obj in vec) {
  obj.readFromFile(fileName);
}

Each obj carries readFromFile's compiled code alongside the data!

Memory is more of a concern than performance in this case, and there is a LOT of data on a constrained system.

Solutions:

  1. Namespace method (great for C++ but not possible in Java)
  2. One static method in obj's class. Executable code is kept in one place at runtime. There is a small overhead to call the method.
  3. A parent class from which obj is derived, which contains the private method readFromFile. Call with super.callPrivateMethod() which calls readFromFile. Messy, and still some memory overhead in each object.
  4. Implement readFromFile outside obj's scope, so in vec's class or in the calling class. This, in my opinion, breaks data encapsulation.

I realize for large amounts of data one explicit object for each triangle is not the best approach. This is only an example.

panlex
  • 265

5 Answers5

25

Methods are not stored on a per-instance basis, even with virtual methods. They're stored in a single memory location, and they only "know" which object they belong to because the this pointer is passed when you call them.

The only extra memory required in C++ is if you're using virtual methods, which require a single extra pointer per instance to point at the virtual method table (in Java of course you always have a base class with virtual methods, Object, so it's unavoidable).

If it worked the way you described, OO languages would not be very popular! Feel free to add as many methods as you need to your objects. It won't affect their memory usage.

vrostu
  • 934
  • 9
  • 6
7

Regardless of how much overhead is involved in calling a static method, regardless of poor OO design, and possible headaches down the road, doesn't it use less memory at runtime?

This is rather complicated, but I would say "mostly no".

3

A method should be "static" (many languages use the term "class method" which is much better) if it doesn't refer to an instance of the class. It should be an instance method if it refers to an instance of the class.

Making a design decision based on the vague possibility of some memory savings instead of the proper use of class methods and instance methods is a very, very, very bad idea.

gnasher729
  • 49,096
2

In principle, there's only one copy of the code, whether it's static member functions or not:

  • In C++ you can easily verify this by looking at the assembler list of the generated code.
  • I'm not Java expert, but from the JNI specification you can deduce it's the same logic: you can fetch a single reference to a function and call it many times for different objects (passing it a class reference as argument, as well as the object reference if it's not a static method).

Using a static or a non-static function will hence not change the memory footprint.

There is in reality a very very small difference, both in the code generated as well as in the memory consumed on the stack during the execution time of the function:

  • A call to the non-static function requires to pass a reference/pointer to the object on which the function/method is applied. This requires usually an additional push and a pop instructions in the calling sequence.
  • A call to a static function doesn't require this overhead.

But this is truly negligible: we are speaking of one or two machine instructions more or less compared to the full code. So it's definitively not something to worry about.

The stack consumption difference at run-time is limited to the time of the execution of the function, to the size of a pointer. This is also negligible, unless you are thinking of a a function called recursively a huge number of times (several millions of time).

So in conclusion, I fully share gnasher729 opinion: premature optimization is the root of all evil. If the function is independent of the object make it static and that should be the only criteria.

Oliv
  • 123
  • 3
Christophe
  • 81,699
0

It is easy to focus on things like optimizing memory usage or reducing lines of code but when you start having to maintain programs that people use/break and other programmers add functionality to...and possibly introduce bugs...not that your original program could possibly have bugs that made it past testing you will see that focusing on readability/maintainablility of the code may be more important. I could make a high speed bit array to track a series of data points but unless I wrapped that bit array in an object with understandable accessors the next programmer to touch that code will probably not use it, replace it or do some hideous witchcraft to it.