2

I have come across the term "garbage disposal" and now I'm worried about using up too much memory. Apparently (correct me if I'm wrong) every time an object is created, memory is reserved for it, and that object must be properly disposed of if not needed anymore. My question is if one should avoid instantiating objects then whenever possible. For example, if a function requires a coordinate as arguments, should I have

example(int x,int y)

or is it okay to have

example(Point p)

and during the actual call I do something like

example(new Point(5,5));

I'm worried about not slowing down the application, so I would like to know if having primitives as arguments is better than having objects which will usually be instantiated on the spot

Abbrew
  • 31
  • 2
  • 5
    A garbage disposal is an electrical appliance that you install under your kitchen sink... Perhaps you mean "Garbage Collector?" – Robert Harvey Mar 25 '15 at 06:05
  • possible duplicate of [When should code favour optimization over readability and ease-of-use?](http://programmers.stackexchange.com/questions/162629/when-should-code-favour-optimization-over-readability-and-ease-of-use) – gnat Mar 25 '15 at 07:21
  • 2
    Related [Stack and Heap memory in Java](http://programmers.stackexchange.com/a/263542/40980). You should also give [Java theory and practice: Urban performance legends, revisited](http://www.ibm.com/developerworks/java/library/j-jtp09275/index.html) and pay particular attention to the section on 'escape analysis': "[F]or small objects, the JVM can optimize away the allocation entirely and simply hoist the object's fields into registers." Incidentally, the example listing for this also uses a Point class. –  Mar 27 '15 at 01:57
  • What language are you talking about? Java? C#? Something else? – Rob K Mar 27 '15 at 20:59

2 Answers2

6

It really depends upon the programming language, and the implementation. Read also Scott's book on Programming Language Pragmatics.

Read the wikipage on garbage collection (GC). GC can be quite efficient, read A.Appel old's paper: Garbage Collection Can be Faster than Stack Allocation and for a good overview the GC handbook

Some programming languages, like C, don't even have any objects, and require manual memory management, read more about C dynamic memory allocation.

C++ is slightly better, notably because it has programming idioms like RAII and because of its destructors (implicitly called at end of block).

Java is compiled to JVM bytecode which generally has quite a good GC.

Functional languages like Ocaml, SML, Haskell, Common Lisp implementations (and most JVMs) usually have good generational GC which handles differently fresh values or objects and older ones.

When coding, favor readable and maintainable code and efficient algorithms. Remember the adage that premature optimization is evil (the compiler is optimizing quite well, and could even optimize example(new Point(x,y)) as example(x,y) in some cases). If you really care, profile and benchmark your application then put your recoding efforts on small hot spots. Don't worry!

Basile Starynkevitch
  • 32,434
  • 6
  • 84
  • 125
  • 2
    Your last paragraph should be on top, really! – Doc Brown Mar 25 '15 at 06:41
  • For Java, [Java theory and practice: Urban performance legends, revisited](http://www.ibm.com/developerworks/java/library/j-jtp09275/index.html) may also be a useful reference. Even beyond the very researched gc, its quite likely that small objects don't even become *really* allocated if they don't escape the scope (or they may be allocated on the stack instead and allow the stack frame to clean them up rather than garbage collection in the heap). –  Mar 27 '15 at 02:00
6

now I'm worried about using up too much memory

You are not talking about a real program, just some "feeling" your programs might use up too much memory? Why? Ask this question when you have a written a program which uses too much memory, not beforehand.

My question is if one should avoid instantiating objects then whenever possible

Short answer: no, not "whenever possible", not "most times", maybe "in some rare cases". The decision to create classes and objects should be guided first and almost by the question if they form proper abstractions for your task or algorithm. Performance or memory optimizations on that level you have in mind should be done when needed, never beforehand.

should I have example(int x,int y) or is it okay to have example(Point p)

Actually, that example might be a little bit misleading, since it will lead to calls

 example(new Point(5,5))

vs.

 example(5,5)

and the latter one looks more readable than the first on a first glance. In a real world program, however, you will probably not have to write something like example(new Point(5,5)) too often, instead you have to process a set of points in a way like this:

foreach(Point p in setOfPoints)
   example(p);

which is more comprehensive than example(p.X,p.Y). And if you have really lots of calls with hard-encoded literals like example(new Point(5,5)), you could provide both example variants as some syntactic sugar. Note that the primary question here is "what makes the program more readable?", not "does this make a slight difference in memory usage on a micro scale level?".

Imagine what happens if you have lots of functions with more than one Point parameter, like

 bool doPointsFormATriangle(Point p1, Point p2, point p3)

vs

 bool doPointsFormATriangle(double x1, double y1, double x2, double y2,double x3, double y3)

you get twice the number of parameters in the second case, and readability of calls to that function decreases by the same factor of two.

Indeed, where I work, I still have to maintain some older programs which were written by a beginners guy some years ago in the style like the second doPointsFormATriangle, with hundreds of function calls passing all 3D points as primitive coordinates. From that experience I can tell you its horrible - so do yourself a favor and avoid that style.

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
  • I think the use of Point is fine, assuming you use Point, and not break it down into its x and y primitives immediately afterwards. That would mean creating an instance only to not use it is somewhat silly. Consider also that Point can always be extended to include useful calculation methods with other points in the future. To achieve the same effect with integer parameters, you'd have to create the instance in the method that requires these calculations. – Neil Mar 25 '15 at 08:36
  • @Neil: what you write sounds like the signature of the function `example` should depend on its implementation. If that is what you meant, I disagree - the signature should depend on what the callers need most, not what is easier to implement. If the `example` function is implemented in using primitives, it may be another reason to provide two variants, one with (x,y) (which may contain the calculation code), and one `example(Point p){return example(p.X,p.Y);}`. – Doc Brown Mar 25 '15 at 10:39
  • What I mean was that if the purpose of Point is purely to pass a parameter to a method, I have to question the usefulness of Point. However, you should generally tend to prefer the use of objects like Point over passing two primitives, but only if you intend to make use of Point. This is, afterall, the scope of object-oriented programming in the first place. If your library is going to accept `Point` just to take the x and y components and put them in some array immediately afterwards, you shouldn't accept `Point` at all. – Neil Mar 25 '15 at 11:00
  • 2
    @Neil: as I wrote, this is about proper abstractions. If you create a library dealing with a "point abstraction", you should provide a class `Point` and design your API around that, and it does not matter if a function of that lib stores the components x and y in separate arrays internally. – Doc Brown Mar 25 '15 at 11:04