Anda di halaman 1dari 9

Java virtual machine

JVM is a virtual machine for Java programs. Source code is compiled to Java bytecode, which is
verified, interpreted or JIT-compiled for the native architecture. The Java APIs and JVM together
make up the Java Runtime Environment (JRE).
Programs intended to run on a JVM must be compiled into Java bytecode (.class, Java class
files).
The JVM verifies all bytecode before it is executed. This verification consists primarily of three
types of checks:

Branches are always to valid locations

Data is always initialized and references are always type-safe

Access to private or package private data and methods is rigidly controlled.

The first two of these checks take place primarily during the verification step that occurs when a
class is loaded and made eligible for use. The third is primarily performed dynamically, when
data items or methods of a class are first accessed by another class.
The Java virtual machine heap is the area of memory used by the JVM for dynamic memory
allocation. The heap is divided into generations:

The young generation stores short-lived objects that are created and immediately garbage
collected.

Objects that persist longer are moved to the old generation.

Class Loading
Java class loading is lazy
A class is loaded and initialized when it (or a subclass) is first accessed
Classname must match filename so class loader can find it
Superclasses are loaded and initialized before subclasses

Initialization Dependencies
class A {
static int a = B.b + 1; //code in A.<clinit>
}
class B {
static int b = 42; //code in B.<clinit >
}
Initialization of A will be suspended while B is loaded and initialized

Object Initialization
Object creation initiated by new (sometimes implicitly, e.g. by + for strings)
JVM allocates heap space for object.

Java Virtual Machine


JVM is divided into several components like the stack, the garbage-collected heap, the registers
and the method area.

The Stack
Stack in Java virtual machine stores various method arguments as well as the local variables of
any method. Stack also keeps track of each and every method invocation. This is called Stack
Frame. There are three registers thats help in stack manipulation. They are vars, frame, optop.
This registers points to different parts of current Stack.
There are three sections in Java stack frame:
Local Variables: contains all the local variables being used by the current method invocation. It
is pointed to by the vars register.
Execution Environment: is used to maintain the operations of the stack itself. It is pointed to by
the frame register.
Operand Stack: is used as a work space by bytecode instructions. It is here that the parameters
for bytecode instructions are placed, and results of bytecode instructions are found. The top of
the operand stack is pointed to by the optop register.

Method Area
This is the area where bytecodes reside. The program counter points to some byte in the method
area. It always keep tracks of the current instruction which is being executed (interpreted). After
execution of an instruction, the JVM sets the PC to next instruction. Method area is shared
among all the threads of a process. Hence if more than one threads are accessing any specific
method or any instructions, synchorization is needed. Synchronization in JVM is acheived
through Monitors.

Garbage-collected Heap
The Garbage-collected Heap is where the objects in Java programs are stored. Whenever we
allocate an object using new operator, the heap comes into picture and memory is allocated from
there. Unlike C++, Java does not have free operator to free any previously allocated memory.
Java does this automatically using Garbage collection mechanism. Till Java 6.0, mark and
sweep algorithm is used as garbage collection logic. Remember that the local object reference
resides on Stack but the actual object resides in Heap only. Also, arrays in Java are objects, hence
they also resides in Garbage-collected Heap.

Garbage collection algorithms

Reference-counting garbage collection


This algorithm reduces the definition of "an object is not needed anymore" to "an object has no
other object referencing to it". An object is considered garbage-collectable if there is zero
reference pointing at this object.
Limitation : cycles
If objects reference one another (and form a cycle), they may be "not needed anymore" and yet
not garbage-collectable.
Mark-and-sweep algorithm
This algorithm reduces the definition of "an object is not needed anymore" to "an object is
unreachable".
This algorithm assumes the knowledge of a set of objects called roots (In JavaScript, the root is
the global object). Periodically, the garbage-collector will start from these roots, find all objects
that are referenced from these roots, then all objects referenced from these, etc. Starting from the
roots, the garbage collector will thus find all reachable objects and collect all non-reachable
objects.
Limitation: objects need to be made explicitly unreachable
Debugger
A debugger is a program that runs other programs to examine variables when problems arise.
Debugger helps finding out followings:

If a core dump happened then what statement or expression did the program crash on?

If an error occurs while executing a function, what line of the program contains the call to
that function, and what are the parameters?

What are the values of program variables at a particular point during execution of the
program?

What is the result of a particular expression in a program?

Debuggers offer more functions such as running a program step by step, stopping (breaking)
(pausing the program to examine the current state) at some event or specified instruction by
means of a breakpoint, and tracking the values of variables.

Gdb is a debugger for C (and C++). It allows to do things like run the program up to a certain
point then stop and print out the values of certain variables at that point, or step through the
program one line at a time and print out the values of each variable after executing each line.

SpiderMonkey
SpiderMonkey has a mark-sweep garbage collection (GC) with an optionally enabled
incremental marking mode. The mark phase uses a mark stack, as required by incremental
marking. Sweeping of objects without finalizers is deferred to a background thread. The JS heap
is partitioned into compartments.

Type system
Is a collection of rules that assign a property called a type to the various constructs such as
variables, expressions, functions or modules a computer program is composed of. The main
purpose of a type system is to reduce bugs in computer programs by defining interfaces between
different parts of a computer program, and then checking that the parts have been connected in a
consistent way.
Type checking
The process of verifying and enforcing the constraints of types type checking may occur
either at compile-time (a static check) or run-time (a dynamic check).
Static type-checking
Static type-checking is the process of verifying the type safety of a program based on analysis of
the source code. If a program passes a static type-checker, then the program is guaranteed to
satisfy some set of type-safety properties for all possible inputs.
Dynamic type-checking
Dynamic type-checking is the process of verifying the type safety of a program at runtime.
Implementations of dynamically type-checked languages generally associate runtime objects
with "tags" containing their type information.

Interpreter vs Compiler
Compiler
A compiler is a piece of code that translates the high level language into machine language.
When a user writes a code in a high level language such as Java and wants it to execute, a
specific compiler which is designed for Java is used before it will be executed. The compiler
scans the entire program first and then translates it into machine code which will be executed by
the computer processor and the corresponding tasks will be performed.
Interpreter
Interpreters also convert the high level language into machine readable binary equivalents. Each
time when an interpreter gets a high level language code to be executed, it converts the code into
an intermediate code before converting it into the machine code. Each part of the code is
interpreted and then execute separately in a sequence and an error is found in a part of the code it
will stop the interpretation of the code without translating the next set of the codes.
The main differences between compiler and interpreter are listed below:

The interpreter takes one statement then translates it and executes it and then takes
another statement. While the compiler translates the entire program in one go and then
executes it.
Compiler generates the error report after the translation of the entire page while an
interpreter will stop the translation after it gets the first error.
Compiler takes a larger amount of time in analyzing and processing the high level
language code comparatively interpreter takes lesser time in the same process.
Besides the processing and analyzing time the overall execution time of a code is faster
for compiler relative to the interpreter.

Static variables
A static variable is a variable that has been allocated statically, whose lifetime extends across the
entire run of the program. This is in contrast to the more ephemeral automatic variables (local
variables are generally automatic), whose storage is allocated and deallocated on the call stack;
and in contrast to objects whose storage is dynamically allocated in heap memory. A variable that
retains the same data throughout the execution of a program.In java static variables are stored in
a special area of the heap called the "permanent generation".
Class attributes are marked with the static keyword, meaning that they can be accessed without
instanciation.
Example:

public class Person{


public static final int TOTAL_PERSONS;
private String firstname;
With this class, we can use Person.TOTAL_PERSONS, but not Person.firstname. To get/set the
first name you first need to create an instance of that class:
Person p = new Person();
p.setFirstname("foo");

Static/Class methods
There are two types of methods:

Instance methods are associated with an object and use the instance variables of that
object. This is the default.
Static methods use no instance variables of any object of the class they are defined in.

Why declare a method static?

Documentation. Anyone seeing that a method is static will know how to call it (see
below). Similarly, any programmer looking at the code will know that a static method
can't interact with instance variables, which makes reading and debugging easier.
Efficiency. A compiler will usually produce slightly more efficient code because no
implicit object parameter has to be passed to the method.

Pass by value vs. pass by reference


When you pass a parameter by value, you are creating a copy of the original variable and the
receiving (method/function) cannot change the original value.
When you pass by reference you are passing a pointer to the original object and therefore any
changes are made to the original value.

In java pass by value is the technique where a copy of the variable is passed to the method as
argument. This value can be modified inside the method but that would not affect the original
value.
Pass by reference is the technique where the reference to the actual variable is passed to the
method as argument. Any changes to this variable would affect and alter the original value.
Usually primitive data types are passed by value and objects are passed by reference in java.
Java is always pass-by-value. The difficult thing can be to understand that Java passes objects as
references and those references are passed by value.
In Java, Objects are passed by reference, and primitives are passed by value.
This is half incorrect. Everyone can easily agree that primitives are passed by value; there's no
such thing in Java as a pointer/reference to a primitive. However, Objects are not passed by
reference. A correct statement would be Object references are passed by value.

Pass by name
Call by name: re-evaluate the actual parameter on every use. For actual parameters that are
simple variables, this is the same as call by reference. For actual parameters that are expressions,
the expression is re-evaluated on each access. It should be a runtime error to assign into a formal
parameter passed by name, if the actual parameter is an expression.
Call-by-name similar to call-by-reference in that you can change the value of the passed in
parameter. It differs from call-by-reference in that the parameter is not evaluated before the
procedure is called but is instead evaluated lazily. That is, it is evaluated when and only when the
parameter is actually used.

Javascript Memory Management


JavaScript values are allocated when things (objects, strings, etc.) are created and
"automatically" free when they are not used anymore. The latter process is called garbage
collection.

Memory lifecycle
Regardless of the programming language, memory lifecycle is pretty much always the same:

Allocate the memory you need

use it (read, write)


Release the allocated memory when it is not needed anymore

Allocation in JavaScript
Value initialization
In order not to bother the programmer with allocations, JavaScript does it alongside with
declaring values.
var n = 123; // allocates memory for a number
var s = "azerty"; // allocates memory for a string
var o = { a: 1, b: null }; // allocates memory for an object and contained values
var a = [1, null, "abra"]; // (like object) allocates memory for the array and contained values
function f(a){ return a + 2; } // allocates a function (which is a callable object)

Javascript always passes by value. However, if you pass an object to a function, the "value" is
really a reference to that object, so the function can modify that object's properties but not cause
the variable outside the function to point to some other object.

Anda mungkin juga menyukai