Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Background
I revisited an old (but great) site I had not been to for ages - the Alioth Language Shootout (http://benchmarksgame.alioth.debian.org/).

I started out programming in C/C++ several years ago, but have since then been working almost exclusively in Java due to language constraints in the projects I have been involved in. Not remembering the figures, I wanted to see, approximately, how well Java fared against C/C++ in terms of resource usage.

The execution times were still relatively good, with Java at worst performing 4x slower than C/C++, but on average around (or below) 2x. Due to the nature of the implementation of Java itself, this was no surprise, and it's performance time was actually lower than what I expected.

The real brick was the memory allocation - at worst, Java allocated:

  • a whopping 52x more memory than C
  • and 25x more than C++.

52x the memory ... Absolutely nasty, right? ... or is it? Memory is comparatively cheap now.

Question:
If we do not speak in terms of target platforms with strict limits on working memory (i.e. embedded systems and the like), should memory usage be a concern when picking a general purpose language today?

I am asking in part because I am considering migrating to Scala as my primary language. I very much like the functional aspects of it, but from what I can see it is even more expensive in terms of memory than Java. However, since memory seems to be getting faster, cheaper and more plentiful by the year (it seems to be increasingly hard to find a consumer laptop without at least 4GB of DDR3 RAM), could it not be argued that resource management is becoming increasingly more irrelevant as compared to (possibly implementation-wise expensive) high-level language features which allow for faster construction of more readable solutions?

share|improve this question
26  
Don't forget that just because Java allocates 52x more memory than C for a small benchmark, it doesn't mean it will use 52x more memory for a large application. The lion's share of that memory will be a fixed amount required by the JVM, and the bigger your application gets, the less significant that portion will become. –  Carson63000 Mar 7 '13 at 2:04
4  
If mobile development is irrelevant, than yes. –  JeffO Mar 7 '13 at 2:06
2  
The question is how bad is the Java benchmark vs. C/C++ and what does it mean in terms of choosing between the two languages. I see this as being on-topic, relevant to all programmers, clear, focused, and able to be answered reasonably in its current form. I have voted to reopen. –  GlenPeterson Mar 7 '13 at 4:51
    
Most performance problems are caused and fixed at the design level, not the tool level. Some problems need 1ms granularity and thus require C/C++. If you have leeway, like 10ms, then maybe Scala or Java is a good option. Most input controllers for games operate at the 50-100ms level. Many people today write critical sections in one language and the rest of a program in another. –  GlenPeterson Mar 7 '13 at 4:56
3  
When looking at the "25x more than C++" on this test one needs to take into account the constant addition of the runtime (about 13 Mb). As the problem gets bigger, the runtime memory requirement becomes less as a percentage of the entire program. Where the C++ memory usage is less than 1 MB, if you subtract the C++ memory usage from the Java Memory usage, you will get a fairly constant value. –  MichaelT Mar 7 '13 at 18:29

8 Answers 8

up vote 28 down vote accepted

Memory management is utterly relevant since it governs how fast something appears even if that something has a great deal of memory. The best and most canonical example are AAA-title games like Call of Duty or Bioshock. These are effectively real-time applications that require massive amounts of control in terms of optimization and usage. It's not the usage per se that's the issue but rather the management.

It comes down to two words: Garbage Collection. Garbage Collection algorithms can cause slight hiccups in performance or even cause the application to hang for a second or two. Mostly harmless in an accounting app but potentially ruinous in terms of user experience in a game of Call of Duty. Thus in applications where time matters, garbage collected languages can be hugely problematic. It's one of the design aims of Squirrel for instance, which seeks to remedy the issue that Lua has with its GC by using reference counting instead.

Is it more of a headache? Sure but if you need precise control, you put up with it.

share|improve this answer
10  
-1 "...literally lethal in a game..." - My day job is a safety critical system as in safety of life. The worst that happens in game software is the writer goes bust because its crappy and no one buys it. This is a difference that should not be trivialized. –  mattnz Mar 6 '13 at 23:18
2  
@mattnz Poor choice of words on my part. It has been fixed. It was not my intention to trivialize anything. –  World Engineer Mar 6 '13 at 23:30
17  
@Mattnz: If you're familiar with games, he obviously means that it could be lethal to your character, which is a completely true statement. –  Mason Wheeler Mar 6 '13 at 23:32
7  
+1 because the answerer has a diamond so the answer must be right. –  psr Mar 6 '13 at 23:38
5  
Realtime garbage collectors have existed for ages. –  Jörg W Mittag Mar 7 '13 at 0:26

As with all things, it's a trade-off.

If you are building an application that is going to run on a single user desktop and can reasonably be expected to control a large fraction of the RAM on that machine, it may be worth it to sacrifice memory usage for implementation speed. If you're targeting that same machine but you're building a small utility that is going to be competing with a bunch of other memory-hungry applications that are running simultaneously, you may want to be more cautious about that trade-off. A user may be fine with a game that wants all of their memory when it's running (though, as World Engineer points out, they'll be concerned if the garbage collector decides to pause the action periodically to do a sweep)-- they are likely to be much less enthused if the music player they run in the background while doing other things decides to gobble up a ton of memory and interferes with their ability to work. If you're building a web-based application, any memory you use on the servers limits your ability to scale out forcing you to spend more money on more application servers to support the same set of users. That can have a major impact on the economics of the company so you may want to be very cautious about making that trade-off.

share|improve this answer
1  
+1 for identifying its about economics. –  mattnz Mar 6 '13 at 23:19

As Donald Knuth said, premature optimization is the root of all evil. Unless you have a reason to believe that memory is going to be the bottleneck, don't worry about it. And given that Moore's law is still delivering increased memory capacity (even though we're not getting faster single-threaded code out of it), there is every reason to believe that in the future we'll be even less constrained on memory than we are today.

That said, if optimization is not premature, by all means do it. I'm personally working on a project right now where I understand my memory usage in great detail, I actually need precise control, and a garbage sweep would kill me. I am therefore doing this project in C++. But that choice seems to be a once every several years event for me. (Hopefully in a few weeks I won't touch C++ again for a few more years.)

share|improve this answer
2  
This attitude is how we end up with bloated enterprise software on incredibly slow computers that keep paging. Everyone says 'Sure my app takes more memory, but who cares, it's practically free!' and then you end up with a full stack of memory-hungry apps that make a 4GB RAM machine run slower than a 512MB RAM machine did 10 years ago. –  MrFox Mar 7 '13 at 18:18
    
@MrFox Actually the problem with enterprise software is that the people who decide to use it aren't the people who suffer with it. See lists.canonical.org/pipermail/kragen-tol/2005-April/000772.html for an excellent description of why it is broken. As for the rest, did you miss my pointing out that worrying about memory usage sometimes is necessary? –  btilly Mar 7 '13 at 21:00

The real brick was the memory allocation - at worst, Java allocated a whopping 52x more memory than C, and 25x more than C++.

Do you understand the numbers you base your question upon?

  • How much memory was allocated?
  • What were the programs doing?

When there's a big disparity between those Java and C programs, it's mostly the default JVM memory allocation versus whatever libc needs:

  • n-body
    Java program 13,996KB :: C program 320KB :: Free Pascal 8KB

Look at the tasks that do require memory to be allocated (or use additional buffers to accumulate results from multicore programs):

  • mandelbrot
    Java program 67,880KB :: C program 30,444KB

  • k-nucleotide
    Java program 494,040KB :: C program 153,452KB

  • reverse-complement
    Java program 511,484KB :: C program 248,632KB

  • regex-dna
    Java program 557,080KB :: C program 289,088KB

  • binary-trees
    Java program 506,592KB :: C program 99,448KB

...should memory usage be a concern when picking a general purpose language today?

It depends whether the specific usage, for your specific approach to solving the specific problems you need to solve, will be constrained by the specific limits of available memory on the specific platform that will be used.

share|improve this answer
3  
Your point about digging into the numbers is valid, and that site certainly has quite a few disclaimers surrounding their tests. Your answer would be strengthened by directly addressing the core question, which is "should memory usage be a concern?" –  GlenH7 Mar 7 '13 at 16:36
1  
Excellent answer that salvaged relatively poor question (vaguely specified benchmark is even worse than premature optimization:). Data that supports the analysis is well presented, concrete and makes a great food for thought. Definitely worth an "exemplary answer" bounty. –  gnat Mar 7 '13 at 18:00

It depends on a number of factors, especially the scale at which you're working.

Just for the sake of argument, let's assume a 30x difference in memory and 2x in CPU usage.

If you're dealing with an interactive program that would take 10 megabytes of memory and 1 millisecond of CPU if written in C, it's pretty much inconsequential -- 300 megabytes of memory and 2 milliseconds to execute is normally entirely irrelevant on a typical desktop, and unlikely to mean much even on a phone or tablet.

The difference between needing around half the resources of a server to needing 15 servers is a much bigger step -- especially since scaling out to 15 servers is likely to require a lot of extra work to develop instead of less. As far as future expansion goes, the same factors you mention tend to suggest that unless your customer base undergoes massive growth, that if it'll run on one server now, chances are pretty good that when you outgrow that server, you'll be able to replace that with one newer server without any problem.

The other factor you really need to consider is exactly how much difference in development cost you're going to see for your particular task. Right now, you're basically looking at one side of an equation. To get a good idea of costs vs. benefits, you (obviously enough) need to look at both costs and benefits, not just one in isolation. Right now, you're basically looking at one side of an equation. The real question is basically: "is x greater than y?" -- but you can't determine that by looking only at x. You clearly need to look at y as well.

share|improve this answer
2  
+1 for noting scale. Take a look at this article to really apprecaite resource management in the large scale. –  Guy Coder Mar 7 '13 at 2:01

Memory management is absolutely relevant in today's world. However, not in the way you might expect. Even in garbage collected languages you have to ensure you don't have a reference leak

You're doing something wrong if this is your code:

static List<string> Cache;

...
Cache.Add(foo); //and then never remove anything from Cache

Garbage collection can't magically know you will never use some reference ever again unless you make it so you can't use it again, ie by doing Cache=null, you effectively alert the garbage collector that "hey I'm not going to be able to access it anymore. Do what you will with it"

It's more complicated than that, but reference leaks are just as, if not more, harmful than traditional memory leaks.

There are also some places where you can't fit a garbage collector into. For instance, the ATTiny84 is a microcontroller with 512 bytes of code ROM, and 32 bytes of RAM. Good luck! That's an extreme, and probably wouldn't be programmed in anything but assembly, but still. Other cases you might have 1M of memory. Sure, you could fit a garbage collector, but if the processor is very slow (either by limitations, or to preserve battery), then you're not going to want to use a garbage collector cause it's too expensive tracking what a programmer could know.

It also gets significantly more difficult to use garbage collection when you need guaranteed response times. Like, if you have a heart monitor or something and when it receives a 1 on some port, you need to guarantee you can respond to it with a proper signal or something within 10ms. If in the middle of your response routine the garbage collector needs to make a pass and it ends up taking 100ms to respond, that might be someone dead. Garbage collection is very difficult, if not impossible, to use when timing requirements need to be guaranteed.

And of course, even on modern hardware, there is some cases where you need that extra 2% of performance by not worrying about the overhead of a garbage collector.

share|improve this answer

For people dealing with "big data" memory management is still a huge issue. Programs in astronomy, physics, bioinformatics, machine learning, etc., all have to deal with multi-gigabyte datasets, and the programs run a lot faster if the relevant portions can be kept in memory. Even running on a machine with 128GB of RAM doesn't solve the problem.

There is also the matter of taking advantage of GPU, though perhaps you'd classify that as an embedded system. Most of the hard thinking in using CUDA or OpenCL boils down to memory management issues in transferring data from main memory to GPU memory.

share|improve this answer

To be fair, a lot of Java out there indulges in some truly and pointlessly class-explosive patterns that just murder performance and hog memory but I do wonder how much of that memory is just the JVM which in theory (heh) let's you run the same app in multiple environments without having to completely rewrite new ones. Hence the design tradeoff question it all boils down to: "How much of your users memory is such a development advantage worth to you?"

This is, IMO a perfectly worthwhile and reasonable tradeoff to consider. What pisses me off though is the notion that because modern PCs are so powerful and memory is so cheap, we can completely ignore such concerns and bloat features and bloat code and be lazy about choices to the point where it seems like a lot of the stuff I do on a windows PC now, takes just as long as it did in Window '95. Seriously though, Word? How much new crap that 80% of their user-base actually needs could they have possibly added in 18 years? Pretty sure we had spellcheck pre-windows right? But we were talking memory which is not necessarily speed if you have plenty of it so I digress.

But of course if you can get the app done in 2 weeks at the cost of maybe a few extra megabytes rather than 2 years to get the needs-only-a-few-K version, it's worth considering how a few megs compares to (I'm guessing) 4-12 gigs on the average users machine before scoffing at the idea of being so sloppy.

But what does this have to do with Scala beyond the tradeoff question? Just because it's garbage collection, doesn't mean you shouldn't always be trying to think about the flow of data in terms of what's in scopes and closures and whether it should be left sitting around or used in such a way that it will be deallocated by GC when it's no longer needed. That's something even us JavaScript UI web devs have had to think about and hopefully will continue to as we spread into other problem domains like the perf-savvy cancer (that you all should have killed with Flash or Applets or something when you had the chance) that we are.

share|improve this answer

protected by maple_shaft Mar 7 '13 at 2:45

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.