What is the difference between JDK and JRE?
What are their roles and when should I use one or the other?
One difference from a debugging perspective:
To debug into Java system classes such as String and ArrayList, you need a special version of the JRE which is compiled with "debug information". The JRE included inside the JDK provides this info, but the regular JRE does not. Regular JRE does not include this info to ensure better performance.
What is debugging information? Here is a quick explanation taken from this blog post:
Modern compilers do a pretty good job converting your high-level code, with its nicely indented and nested control structures and arbitrarily typed variables into a big pile of bits called machine code (or bytecode in case of Java), the sole purpose of which is to run as fast as possible on the target CPU (virtual CPU of your JVM). Java code gets converted into several machine code instructions. Variables are shoved all over the place – into the stack, into registers, or completely optimized away. Structures and objects don’t even exist in the resulting code – they’re merely an abstraction that gets translated to hard-coded offsets into memory buffers.
So how does a debugger know where to stop when you ask it to break at the entry to some function? How does it manage to find what to show you when you ask it for the value of a variable? The answer is – debugging information.
Debugging information is generated by the compiler together with the machine code. It is a representation of the relationship between the executable program and the original source code. This information is encoded into a pre-defined format and stored alongside the machine code. Many such formats were invented over the years for different platforms and executable files.