I was trying to understand Clojure's garbage collection system. Of course, its all about JVM and its GC. I understood it was parallel mark&sweep, but I couldn't understand how it work. Can someone explain it please?
In addition, I saw some talking about static and dynamic GC. Whats the difference? and what JVM uses?
thanks a lot!
Clojure doesn't implement its own Garbage Collector - it runs on JVM as any other JVM byte code and thus uses whatever garbage collector implementation that is run by the JVM (based on defaults or command line parameters configuration).
Better just to look up Java GC details, here's a page that might help: Understanding Java Garbage Collection.
Related
So basically I only know some basic concept of GC:(
I am new in functional programming language, and when I am studying the Haskell's runtime system, RTS, I found that RTS support GC for the compiled binary from Haskell.
So I am confused with this part, is there a separate process created by RTS that can do GC stuff towards Haskell binaries?
What's more, if so, is there any GC implementation for C/C++ ? (Suppose programmers only use kinda of "smart pointer" to use memory, and they don't need to care about memory management, GC process will take care of it)...? As far as I know, it seems that .net can work in this way... am I right?
is there a separate process created by RTS that can do GC stuff towards Haskell binaries?
Garbage collection does not, in general, require a separate process (e.g., a "background" process), although some virtual-machine garbage collectors might do that (I don't know).
Think of the garbage collector as being merged with the heap allocator. Whenever you ask for some memory to be allocated, you invoke the heap to do so (which may hang for some time before finding a chunk to allocate). With a garbage collector, there is simply an additional step where the garbage collector first checks if it should do some collecting before allocating some memory.
What is central to garbage collection is the instrumentation (or annotation) of the memory to be able to infer which chunks of memory are still referred to / reachable. This kind of instrumentation simply implies additional operations during certain key points, like allocation, deallocation (if there is an explicit mechanism for it), and setting / getting pointer values (which are usually "hidden" under-the-hood in a garbage collected language, as opposed to languages like C/C++ that have "raw" pointers).
What's more, if so, is there any GC implementation for C/C++ ?
Yes, there are all sorts of GC implementations for C/C++. They are not very popular (AFAIK), probably because C is low-level enough that things are usually manageable, and C++ has RAII (and smart pointers) which almost-completely eliminates the need for GC.
But if you really want GC for C/C++, you can certainly get it. There are both non-deterministic GC libraries (similar to JVM or .NET) and deterministic GC libraries (similar to PHP or Python).
As far as I know, it seems that .net can work in this way... am I right?
Yeah, .NET like Java, is garbage collected. From a GC user's perspective, .NET is about the same as the JVM, as far as I know.
So I am confused with this part, is there a separate process created by RTS that can do GC stuff towards Haskell binaries?
No. Why would there be? You don't need a separate process to do GC. The Java JVM doesn't need a separate process. You seem to have some confusion somewhere. All you need is some code in the runtime library.
What's more, if so, is there any GC implementation for C/C++ ?
Yes.
As far as I know, it seems that .net can work in this way... am I right?
If you mean that .NET has GC you're correct. If you mean that it's done via smart pointers or a separate process you're wrong.
If I had to guess, I'm pretty sure the answer is Clojure, but I'm not sure why. Logically (to me) it seems like ClojureScript should be faster:
Both are "dynamic", but ClojureScript
Compiles to JavaScript, running on V8
V8 engine is arguably the fastest dynamic language engine there is
V8 is written in C
whereas Clojure:
Is also dynamic
Runs in JVM, which has no built-in dynamic support, so I'm thinking thus JVM has to do whatever V8 is doing too, to enable dynamic support
and Java is slower than C
So how could Clojure be faster than ClojureScript? Does "dynamic" mean something different when saying JavaScript is dynamic and Clojure is dynamic? What am I not seeing?
(Of course if ClojureScript is indeed faster, then is the above reasoning correct?)
I guess, what does Clojure compile to....is at least part of the question. I know the JVM part can't just be a plain interpreter (otherwise ClojureScript would be faster), but Clojure can't compile to regular bytecode, as there's no "dynamic" in the JVM. So what's the difference between how ClojureScript is compiled/executed and how Clojure is compiled/excecuted and how plain Java is compiled/executed, and the performance differences implied in each?
Actually, V8 is written in C++. However, does basically the same thing as the JVM, and JVM is written in C. V8 JITs Javascript code and executes the JIT'd code. Likewise the JVM JIT compiles (or hotspot compiles) bytecode (NOT Java) and executes that generated code.
Bytecode is not static, as Java is. In fact it can be quite dynamic. Java, on the other hand is mostly static, and it is not correct to conflate Java with bytecode. The java compiler transforms Java source code into bytecode, and the JVM executes the bytecode. For more information, I recommend you look at John Rose's blog (example). There's a lot of good information there. Also, try to look for talks by Cliff Click (like this one).
Likewise, Clojure code is directly compiled to bytecode, and the JVM then does the same process with that bytecode. Compiling Clojure is usually done at runtime, which is not the speediest process. Likewise the translation of Clojurescript into Javascript is not fast either. V8's translation of Javascript to executable form is obviously quite fast. Clojure can be ahead of time compiled to bytecode though, and that can eliminate a lot of startup overhead.
As you said, it's also not really correct to say that the JVM interprets bytecode. The 1.0 release did that more than 17 years ago!
Traditionally, there were two compilation modes. The first mode is a JIT (Just in Time) compiler. Where bytecode is translated directly to machine code. Java's JIT compiling executes fast, and it doesn't generate highly optimized code. It runs OK.
The second mode is called the hotspot compiler. The hotspot compiler is very sophisticated. It starts the program very quickly in interpreted mode, and it analyzes it as the program runs. As it detects hotspots (spots in the code that execute frequently), it will compile those. Whereas the JIT compiler has to be fast because nothing executes unless it's JIT'ed the hotspot compiler can afford to spend extra time to optimize the snot out of the code that it's compiling.
Additionally, it can go back and revisit that code later on and apply yet more optimizations to it if necessary and possible. This is the point where the hotspot compiler can start to beat compiled C/C++. Because it has runtime knowledge of the code, it can afford to apply optimizations that a static C/C++ compiler cannot do. For example, it can inline virtual functions.
Hotspot has one other feature, which to the best of my knowledge no other environment has, it can also deoptimize code if necessary. For example, if the code were continually taking a single branch, and that was optimized and the runtime conditions change forcing the code down the other (unoptimized) branch and performance suddenly becomes terrible. Hotspot can deoptimize that function and begin the analysis again to figure out how to make it run better.
A downside of hotspot is that it starts a bit slow. One change in the Java 7 JVM has been to combine the JIT compiler and the hotspot compiler. This mode is new, though, and it's not the default, but once it is initial startup should be good and then it can begin the advanced optimizations that the JVM is so good at.
Cheers!
This question is hard to answer precisely, without reference to a specific benchmark task (or even specific versions of Clojure or ClojureScript).
Having said that, in most situation I would expect Clojure to be somewhat faster. Reasons:
Clojure usually compiles down to static code, so it doesn't actually do any dynamic lookups at runtime. This is quite important: high performance code often produces bytecode that is very similar to statically typed Java. The question appears to be making the false assumption that a dynamic language has to do dynamic method lookups at runtime: this is not always the case (and usually isn't in Clojure)
The JVM JIT is very well engineered, and I believe it is currently still a bit better than the JavaScript JITs, despite how good V8 is.
If you need concurrency or need to take advantage of multiple cores then clearly there is no contest since JavaScript is single-threaded.....
The Clojure compiler is more mature than ClojureScript, and has had quite a lot of performance tuning work in recent years (including things like primitive support, protocols etc.)
Of course, it is possible to write fast or slow code in any language. This will make more of a difference than the fundamental difference between the language implementations.
And more fundamentally, your choice between Clojure and ClojureScript shouldn't be about performance in any case. Both offer compelling productivity advantages. The main deciding factor should be:
If you want to run on the web, use ClojureScript
If you want to run on the server in a JVM environnment, use Clojure
This is not so much an answer as an historical comment: Both the HotSpot VM and the V8 js engine can have their origins traced to the Self project at Sun Microsystems, which I think prototyped a lot of the technology that allows them to run as fast as they do. Something to consider when comparing them both. I would've posted this as a comment but the reputation system prevented me.
I am supporting a C/Cpp application and have resolved few memory leak issues by creating objects. Since it is provided by the third party API, it is told that the objects gets destructed by the API itself.
I could manage to fix the issue and test my application without any issue. But i still doubt my fix for memory leak. I want to do profiling and i am in need of a Cpp tool that can tell me if there are chances of memory leaks in the code given a CPP file.
Is there a tool of that sort? Any help is greatly appreciated.
Thanks,
~Jegan
You are probably looking for a dynamic analysis tools, not a profile. For Linux, there's valgrind. For windows some good commercial solutions are Purify and Insure++.
Give valgrind a try, it's by far the best memory analysis tool I've come across. It only runs on *nix, but you haven't stated your platform.
We're using MemoryValidator from http://www.softwareverify.com/.
It provides a fully functional 30 day trial, so you can test it before buying.
Single license from 179$ (each for 10 licenses), up to 299$ (1 license). And it is really worth it's price. Enables you to find the cause for leaks within a minute.
Also check the other tools they're providing: performance validator, bug validator and so on.
Great tool once you know how to handle it :-)
Is it possible to use SGen garbage collector (from the mono runtime) in coventionnal C/C++ programs ?
I think mono used also the Boehm-Demers-Weiser conservative garbage collector that can be used in C/C++ programs.
There are very few dependencies on the rest of the Mono code in SGen, so it should be easy to extract it out and adapt to other uses.
The major difference from the Boehm collector is that it currently doesn't support a non-precise mode for heap objects, so you can't use it to replace malloc easily.
It would work great, though, for managing objects for which you could provide precise reference information.
Not sure about the garbage collector that you have specified. But do you really need to use a GC on a C++ project? I never felt the use of a GC in my C++ projects. You should be good if you follow the best practices and use a decent smart pointer.
I have an application that runs on an embedded processor (ARM), and I'd like to profile the application to get an idea of where it's using system resources, like CPU, memory, IO, etc. The application is running on top of Linux, so I'm assuming there's a number of profiling applications available. Does anyone have any suggestions?
Thanks!
edit: I should also add the version of Linux we're using is somewhat old (2.6.18). Unfortunately I don't have a lot of control over that right now.
As bobah said, gprof and valgrind are useful. You might also want to try OProfile. If your application is in C++ (as indicated by the tags), you might want to consider disabling exceptions (if your compiler lets you) and avoiding dynamic casts, as mentioned above by sashang. See also Embedded C++.
if your Linux is not very limited then you may find gprof and valgrind useful
On a related note, the C++ working group did a technical report on the performance cost of various C++ language features. For example they analyze the cost of dynamic_casting one or 2 levels deep. The reports here http://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf and it might give you some insight into where the pain points in your embedded application might be.
gprof may disappoint you.
Assuming the program you are testing is big enough to be useful, then chances are the call tree could be pruned, so the best opportunities for optimization are function/method calls that you can remove or avoid. That link shows a good way to find them.
Many people approach this as sort of a hierarchical sleuthing process of measuring times.
Or you can simply catch it in the act, which is what I do.