[java] Java disadvantages

Started by
42 comments, last by Luckless 16 years, 11 months ago
Hi ive been reading up on java and found some benefits over using it that c++ like automatic garbage collection and memeory allocation, but also found java programs are alot slower then the programe being developed in c++ Is the reason for this because of the memory allocation? can someone clear this up for me? and where is java language best used? networking but why? thanks
Advertisement
Quote:Original post by shamy
Hi ive been reading up on java and fbut also found java programs are alot slower then the programe being developed in c++


To say that you've found Java programs to be slower implies that you've tested them yourself. What I think you are saying is that you've read that they are slower, which means your information is coming from old or misinformed sources. Early versions of Java interpreted the byte code at runtime. So, yes, they were slow. For a while now, though, Sun's JVM has been able to compile the code at runtime. Unfortunately, many people who do not use Java, or haven't used in years, are happy to go around and with complete confidence tell people it's slow today. Anyone who bothers to check for themselves will know otherwise.

When a Java app is first launched, the byte code is run in interpreted mode for several iterations. In the background, the JVM analyzes the code that is being executed and compiles "hot spots" (the modern JVM is also known as Hotspot compiler). These compiled sections of code are no longer interpreted, but executed much the same way as a compiled C++ app. The JVM has the benefit of being able to optimize the compiled segments to the user's hardware. Statically compiled languages, such as C++, must have optimizations configured at compile time. When shipping a game, for example, it is usually compiled with optimizations for the lowest common denominator. In practice, that's good enough and all is well. But Java is able to get more customized optimizations because it can detect the hardware are runtime, before compiling the hot spots. And if the user upgrades his CPU, future JVMs that support it will be able to take advantage of its new features, meaning the developer gets a free performance boost.

Additionally, each new release of Java optimizes the standard API internals, the garbage collectors (there are more than one to choose from so that you can tune your app for optimal performance), and the JVM. All of these together usually equate to a performance boost for existing apps and, of course for new ones.

Quote:Is the reason for this because of the memory allocation? can someone clear this up for me?


Java memory allocation is actually more efficient than that of C++. There's been a lot of documentation written about this. I don't have the links handy right now, but there are several articles at IBM developer works which discuss Java topics like memory management and performance myths.

To be sure, there is a lot going on behind the scenes. From array bounds checking to garbage collection, Java's safety and security features are not free. Still, many of the features Java provides out of the box are implemented manually in robust C++ applications anyway (and often turned off in production code for 'performance reasons', defeating the purpose).

So since its early days, Java has greatly closed the gap in performance differences with statically compiled native code. Considering the amount of overhead involved (constant analysis by the runtime compiler, safety & security features, garbage collection, etc...), it's hard to believe that Java programs can perform well at all. But they really can. Still, it's quite possible (as with any language) to structure a Java program such that it performs poorly. This can happen when you don't understand the basics of Java memory management, or when you bring C++ idioms into Java applications. Benchmarks by C++ programmers are notorious for this. They almost always benchmark the interpreted phase of execution, before the JVM has had a chance to complete its analysis and compile the code.

Quote:and where is java language best used? networking but why?


Java shines in networking partly because it was built for it. There are two networking APIs in the standard library, one dead easy to use but with scalability limitations, another that is highly scalable but a bit more complex to use. Java's built-in thread handling, coupled with the java.util.concurrent API make implementing multi-threaded applications a breeze compared to C++ (though you still need to know what you are doing, it's easier to pick up). Server applications will almost always require some amount of multi-threading.

But you can also use Java for 3D games, desktop applications, and a host of other application types (it might not be the best language with which to create an operating system, but that didn't stop people from making one.

Since this is a game development community, you might want to check out the JMonkeyEngine. It's currently being used by NCSoft on an as-yet-unannounced project. Check out the screen shots page to see other Java games being developed with the engine (the MMOG called Spirits and the hockey game on that page are both quite impressive).

So to sum up, the last thing you need to worry about with modern Java is performance. The latest version has shown huge performance gains over the previous. But that brings up the biggest problems you have to worry about: JRE market penetration and the distribution of your app.

To cover the broadest market possible and still get decent performance, you'd be safest using Java 1.4.2. That means you don't get the benefits of the features introduced in 1.5, nor the performance enhancements that came with the restructuring of the byte code layout in 1.6. However, any users running the latest version will still see performance benefits over raw 1.4. On Windows, you could bundle the JRE with your app, but that increases download size and may not be appropriate for small games (however, since Java is GPLed now, the door is open for shipping with stripped down JREs). On Mac, you have no choice but to use whichever version the user has installed. Java 1.5 only runs on versions of Mac OS X 10.3 (or was it 10.2?) and later. I'm not sure if the final of 1.6 has been released on Mac yet or not, but it will further restrict the versions of Mac OS X available.

Anyway, these are both solved problems. Several indies are developing and shipping Java games (check out ThreeRings, PuppyGames, and Oddlabs as examples). There are other little nitpicks to be concerned with, particularly for people who have a background in C++ and can't seem to "think in Java", but none of them should be deal breakers. And just to make sure you get the point, Java performance is only a problem for people who don't use Java. People who do use it for game development understand that Java is not slow and will usually exceed your performance goals.

[Edited by - Aldacron on April 26, 2007 1:29:20 PM]
Quote:Original post by shamy
... java programs are alot slower then the programe being developed in c++


eesh... do we have to go over this again? C++ is faster in some cases, Java is faster in others. If you like Java use Java, if you don't, use C++ (or Python, C, VB, Delphi, COBOL, etc).

Quote:Original post by shamy
and where is java language best used?


Everywhere, of course(*).

Cheers,
Brett

(* This opinion may not be relevant to the real world)
Automatic garbage collection counts as both an advantage and disadvantage. It can be a disadvantage because you don't get any features for free- it costs extra processor time and extra memory.

In terms of raw speed- I know that Java can in theory be faster than C++ because they do lots of optimizations that C++ can't do. I don't think the reality has caught up to this theory yet, maybe some day it will.

Another disadvantage is the restrictiveness of the language. Some people find it annoying that you can't use macros, operator overloading, define multiple classes per file, have files with different names than their classes, or stuff like that. Java has many rules that make writing code kind of a pain. (Although you could also consider all these rules an advantage- they generally make the code better and easier to maintain)

The fact that not everyone has Java installed is a disadvantage, it means they need to complete a second download to run your java app (it's a ~13mb install I think).

In my opinion the biggest disadvantage is the lack of widespread adoption in the developer world. For any given problem, you can usually find a much better selection of available libraries for C++ than for Java. For example, if you want a free open-source 3d graphics library with lots of features, there are many popular ones for C++ (OGRE, CrystalSpace, Delta3d, Panda3d...). For Java there's only 1 (jME).
The most disadvantage of java for me is that you cannot create objects "on the stack". The stack is the fastest memory allocator and GC available on all platforms and languages. It's a shame the java ignores this fact.
So all objects that are only needed within a method-scope per example need to be garbage collected. Placing such objects on the stack like in C++ would unburden the GC dramatically and also increase performance a lot.

Another drawback is the lack of operator overloading. Especially when deadling with highly mathematical software like 3d games with lost of linear algebra. Defining all vector/matrix operations as operators would increase readability. Java doesn't support this because it doesn't belong to OOP.

So generally there're some cases where pure OOP sucks and hybrid-languages/paradigms may be a better choise.

cu,
Chris
Quote:Original post by Christian Weis
The most disadvantage of java for me is that you cannot create objects "on the stack". The stack is the fastest memory allocator and GC available on all platforms and languages. It's a shame the java ignores this fact.
So all objects that are only needed within a method-scope per example need to be garbage collected. Placing such objects on the stack like in C++ would unburden the GC dramatically and also increase performance a lot.

Another drawback is the lack of operator overloading. Especially when deadling with highly mathematical software like 3d games with lost of linear algebra. Defining all vector/matrix operations as operators would increase readability. Java doesn't support this because it doesn't belong to OOP.


Maybe you should check out this paper:
http://citeseer.ist.psu.edu/wilson92uniprocessor.html

For instance a generational garbage collector can implement memory allocation basically as increasing a pointer by the requested size and returning the previous value of the pointer. This results in an allocation cost similar to a local variable in C/C++. Garbage collection and heap compaction automatically free this memory later on. Since most objects only survive for a short amount of time, only very few data needs to be copied when the heap is garbage collected. So there really is no need to store objects on the stack.

Garbage collection can also be seen as a way to delay the work needed to perform the management of memory. For applications like a word processor for instance, the work to free the memory can effectively be performed while waiting for user input, resulting in higher responsiveness when processing the user input.

Operator overloading is not part of the java language right now, but implementing operator overloading in a java-compiler is not that complicated:
http://www-gs.informatik.tu-cottbus.de/grogra.de/xlspec/ch11s02.html#s-operator-methods
(XL is a language that extends Java by some features)
Be sure you know what you are talking about before you talk about how Java allocates memory. Java creates objects faster than C/C++ can malloc().

http://www-128.ibm.com/developerworks/java/library/j-jtp01274.html

Quote:
In HotSpot JVMs (Sun JDK 1.2 and later), things got a lot better -- the Sun JDKs moved to a generational collector. Because a copying collector is used for the young generation, the free space in the heap is always contiguous so that allocation of a new object from the heap can be done through a simple pointer addition, as shown in Listing 1. This makes object allocation in Java applications significantly cheaper than it is in C, a possibility that many developers at first have difficulty imagining. Similarly, because copying collectors do not visit dead objects, a heap with a large number of temporary objects, which is a common situation in Java applications, costs very little to collect; simply trace and copy the live objects to a survivor space and reclaim the entire heap in one fell swoop. No free lists, no block coalescing, no compacting -- just wipe the heap clean and start over. So both allocation and deallocation costs per object went way down in JDK 1.2.
"None of us learn in a vacuum; we all stand on the shoulders of giants such as Wirth and Knuth and thousands of others. Lend your shoulders to building the future!" - Michael Abrash[JavaGaming.org][The Java Tutorial][Slick][LWJGL][LWJGL Tutorials for NeHe][LWJGL Wiki][jMonkey Engine]
Quote:
Java memory allocation is actually more efficient than that of C++.

Quote:
Java creates objects faster than C/C++ can malloc().

That's bull actually. What both of you probably meant to say was that memory allocation in a typical Java application has reduced costs when compared to a similar application written in C/C++. It's not that these costs are part of the languages themselves, it's part of your application's / JVM's implementation.

As an example, Sun's HotSpot JVM requires that the heap's virtual addresses are contiguous, thus allowing the JVM to allocate new objects on a previously allocated heap chunk by simply doing some pointer arithmetic - that's quite fast as you might imagine.

What people usually don't get though, is the fact that this custom memory allocation scheme could of course also be implemented in your "average" C/C++ application - after all, that's just what the JVM is at it's heart (you would have to evaluate situations where this made sense, obviously).
Quote:Original post by Celvin
What people usually don't get though, is the fact that this custom memory allocation scheme could of course also be implemented in your "average" C/C++ application - after all, that's just what the JVM is at it's heart (you would have to evaluate situations where this made sense, obviously).


It cannot, for a very simple reason: in C++ (and, worse, C), objects cannot be relocated transparently. This means that once an object is created, it cannot be moved, which prevents you from filling up holes left by previous deallocations. This, in turn, means that you will either lose insane amounts of memory to fragmentation, or will have to include fragmentation-handling in your allocation scheme.

Java can relocate objects, which means that no fragmentation occurs, which means faster allocation.
Quote:Original post by pinacolada
In terms of raw speed- I know that Java can in theory be faster than C++ because they do lots of optimizations that C++ can't do. I don't think the reality has caught up to this theory yet, maybe some day it will.


When making a statement like this, can you also provide the basis for this statement? I'm not saying it's right or wrong, just wondering what exact data you're basing it on.


Quote:Original post by pinacolada
For Java there's only 1 (jME).


Not quite true. There's also Xith3D and Aviatrix3D. Java3D, too, although it's pretty much obsolete from what I've seen of it. There are also Irrlicht bindings for Java. And OGRE bindings for Java. Compared to the multitude of graphics engines for C++, this is still little however.

This topic is closed to new replies.

Advertisement