Will local variables declared in a Java function automatically be deallocated? - java

If a variable is declared within a function in Java, will that variable be deallocated automatically upon that function's completion regardless of its type? Would the memory occupied by a primitive type, a non-primitive Object, and/or an array of either primitives or Objects be freed up once that variable's scope has been exited?

Primitive types in Java are allocated on the stack, so their memory is automatically deallocated when they go out of scope. Object references are primitives which are similarly managed, but the objects themselves are garbage collected. They will be removed automatically by the garbage collector, but it is not guaranteed how long that will take.
The JVM garbage collector automatically runs when the memory pressure becomes tight, so as long as there are no references to an object anymore, you can effectively make the assumption that its memory will be freed.

If there are no reference to the object, Garbage collector will remove it automatically. But we cant say when will that happen.
This article have a pretty good explanation about how garbage collector works.

in addition to Allexis King's Answer
there is one more technique in newer Java/ JVM which decides whether local object should be allocated in Stack or Heap. local objects allocated in stack by this technique will be de-allocated when it goes out of scope
Escape Analysis
Escape analysis is a technique by which the Java Hotspot Server Compiler can analyze the scope of a new object's uses and decide whether to allocate it on the Java heap.
Escape analysis is supported and enabled by default in Java SE 6u23 and later.

Related

Memory Allocation in Java for Parameters

Would the data in the following statement be stored as automatic memory allocation, or dynamic memory allocation or both
myFunction(new MyClass());
Thank You!
The terms “automatic memory allocation” and “dynamic memory allocation” make no sense in the context of Java. In Java, all memory is managed by the execution environment.
In other programming languages, the terms “automatic storage” and “dynamic storage” are used to distinguish between storage, which is automatically deallocated when going out of scope, and storage, which requires an explicit deallocation action performed by the application. In Java, there are no explicit deallocations at all. You will find that people and literature continue to distinguish between stack and heap, where only the latter contains objects, whose lifetime may exceed the execution of the method in which they were created. This, however, is only a logical separation, which might not reflect how a particular JVM implementation actually works.
The Java® Language Specification doesn’t mandate much details about the workings of this. There are only two spots at all:
15.12.4.5. Create Frame, Synchronize, Transfer Control
A method m in some class S has been identified as the one to be invoked.
Now a new activation frame is created, containing the target reference (if any) and the argument values (if any), as well as enough space for the local variables and stack for the method to be invoked and any other bookkeeping information that may be required by the implementation (stack pointer, program counter, reference to previous activation frame, and the like). If there is not sufficient memory available to create such an activation frame, a StackOverflowError is thrown.
 
17.4.1. Shared Variables
Memory that can be shared between threads is called shared memory or heap memory.
All instance fields, static fields, and array elements are stored in heap memory. In this chapter, we use the term variable to refer to both fields and array elements.
Local variables (§14.4), formal method parameters (§8.4.1), and exception handler parameters (§14.20) are never shared between threads and are unaffected by the memory model.
Note that this is the only place where the term “heap” is used as memory type and how it’s actually defined here…
The sections §15.9.4. Run-Time Evaluation of Class Instance Creation Expressions and §15.10.2. Run-Time Evaluation of Array Creation Expressions are much more vague, saying that “space is allocated” and an OutOfMemoryError is thrown if not enough space is available, and nothing more.
So if you go the route of distinguishing between stack and heap, you can say that your code myFunction(new MyClass()); will cause a heap allocation for an instance of MyClass, followed by a stack allocation for the activation frame of the actual implementation of the myFunction method. Not that it matters for any practical purpose.
If you want to dig more into the way, JVMs may implement it, you may refer to the Java® Virtual Machine Specification instead:
2.5.2. Java Virtual Machine Stacks
Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread. A Java Virtual Machine stack stores frames (§2.6). A Java Virtual Machine stack is analogous to the stack of a conventional language such as C: it holds local variables and partial results, and plays a part in method invocation and return. Because the Java Virtual Machine stack is never manipulated directly except to push and pop frames, frames may be heap allocated. The memory for a Java Virtual Machine stack does not need to be contiguous.
 
2.5.3. Heap
The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.
The heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); objects are never explicitly deallocated. The Java Virtual Machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor's system requirements. The heap may be of a fixed size or may be expanded as required by the computation and may be contracted if a larger heap becomes unnecessary. The memory for the heap does not need to be contiguous
Note, how these definitions only differ in their purpose while not having significant difference in their constraints, i.e. might be fixed-size or resizable and might be contiguous or not, not to speak of the explicit mentioning of the possibility to allocate stack frames on the heap.
There are three groups of memory in Java
Heap - this is where Objects are created and located when you call new MyClass();
Stack - The stack contains stack frames, and stack frames have space allocated for primitives and pointers to Objects in the Heap. Stack frames are allocated on method call and deallocated on method return
String constants: String literals defined at compile time will be added to a String constant pool. At runtime, it is possible to add strings to the pool using String.intern()
That's it
There are two things being allocated in your example;
The expression, new MyClass() allocates an instance of MyClass on the object heap.
The result of the new expression is an object reference. The object reference is saved in the activation record for a call to myFunction(). Activation records are allocated on the calling thread's call stack.
When you create a new object, it often allocated on the heap however with escape analysis, it can be unpacked onto the stack as if it was a local variable.
The only allocation is via new or a capturing lambda (or some native method in rare cases) There isn't any explicit distinction between different ways of allocating an object.

Is there a way to receive object, without having reference to it?

Suppose following code:
Object obj = new Object();
obj = null;
At this point, i don't have any reference to this object, but it's still on the heap, because garbage collection don't happens instantly. Is there a way to re obtain reference on this object, before it'll be collected by GC?
Only possible way that i seen so far is to use Unsafe, which provides direct memory access, but i will need to know where in memory exactly object is allocated. Also, there is Weak\SoftReference, but they are implemented by special GC behavior.
P.S. To predict questions like "Why do you need it?" - Because science is not about why, it's about why not! (c)
This is highly JVM implementation specific. In a naive implementation having memory allocation information associated with each object, you could find an object whose memory has not been freed yet and it seems you are thinking into that direction.
However, sophisticated JVMs don’t work that way. Associating allocation information with each object would create a giant overhead, given that you may have millions of objects in your runtime. Not only regarding memory requirement, but also regarding the amount of work that has to be done for maintaining these information when allocating or freeing an object.
So what makes a part of your heap memory an object? Only the reference you are holding to it. The garbage collector traverses existing references and within the objects found this way, it will find meta information (i.e. a pointer to class specific information) needed to understand how much memory belongs to the object and how to interpret the contained data (to traverse the sub-references, if any). Everything unreferenced is unused per se and might contain old objects or might have never been used at all, who knows. Once all references to an object are gone, there is no information left about the former existence of this object.
Getting to the point, there is no explicit freeing action. When the garbage collector has found surviving objects, they will be copied to a dedicated new place and their old place is considered to be free, regardless of how many objects there were before and how much memory each individual object occupied when it was alive.
When you search memory that is considered to be unused, you may find reminiscences of old objects, but without references to their starting points, it’s impossible to say whether the bit pattern that looks like an object really is a dead object or just a coincidence. Even if you managed to resurrect an object that way, it had nothing to do with your original idea of being able to resurrect a reference, because the gc didn’t run yet.
Note that all modifications to this ordinary life time work by holding another reference to the object. E.g., when the class defines a non-trivial finalize() method, the JVM has to add a reference to the queue of objects needing finalization. Similarly, soft, weak and phantom references encapsulate a reference to the object in question. Also a debugger may keep a reference to an object, once it has seen it.
But for your trivial code Object obj = new Object(); obj = null;, assuming there’s no breakpoint set in-between, there will be no additional reference and hence, no way of resurrecting the object. A JVM may even elide the entire allocation when optimizing the code at runtime. So then you wouldn’t even find remainings of the object in the RAM when searching it as the object effectively never existed.
At this point, i don't have any reference to this object, but it's still on the heap, because garbage collection don't happens instantly.
It is undefined where it is, and it is also undefined whether or not garbage collection happens instantly.
Is there a way to re obtain reference on this object, before it'll be collected by GC?
You already had one and you threw it away. Just keep it.
I will need to know where in memory exactly object is allocated.
There is nothing in standard Java that will tell you that, and no useful way you could make use of the information if you could get it.
Also, there is Weak/SoftReference, but they are implemented by special GC behavior.
I don't see how this affects your question, whatever it is.

Does a static variable go on the permanent gen space on the heap

If I create a static variable in Java, does it automatically go into the perm gen space on the heap? it seems obvious that the answer is yes, but i cannot find the confirmation anywhere.
I know the static variable (also strings and enums) are alive for the life of the JVM so it must go on the permanent heap. IS this correct?
The idea of the "PermGen" is completely implementation-dependent, and JVMs are free to handle the "physical" memory management however makes sense to them--they're not even actually required to provide garbage collection!
The PermGen is just a feature of some JVM implementations (including the Sun/Oracle HotSpot JVM for many years), and it's actually being eliminated with a new approach in the Oracle Java 8 JVM. It's quite likely that JVMs that include the concept of a PermGen will put static variables there for performance, but it's entirely up to the programmer.
JLS #17.4.1 Shared Variables
Memory that can be shared between threads is called shared memory or heap memory.
All instance fields, static fields and array elements are stored in heap memory. In this chapter, we use the term variable to refer to both fields and array elements. Local variables (§14.4), formal method parameters (§8.4.1) or exception handler parameters are never shared between threads and are unaffected by the memory model.
Nice description here By #Stephen:static allocation in java - heap, stack and permanent generation

Is there something like malloc/free in java?

I've never seen such statements though,does it exist in java world at all?
Java's version of malloc is new -- it creates a new object of a specified type.
In Java, memory is managed for you, so you cannot explicitly delete or free an object.
Java has a garbage collector. That's why you never see such statements in your code(which is nice if you ask me)
In computer science, garbage
collection (GC) is a form of automatic
memory management. It is a special
case of resource management, in which
the limited resource being managed is
memory. The garbage collector, or just
collector, attempts to reclaim
garbage, or memory occupied by objects
that are no longer in use by the
program. Garbage collection was
invented by John McCarthy around 1959
to solve problems in Lisp.
new instead of malloc, garbage collector instead of free.
No direct equivalents exist in Java:
C malloc creates an untyped heap node and returns you a pointer to it that allows you to access the memory however you want.
Java does not have the concept of an untyped object, and does not allow you to access memory directly. The closest that you can get in Java to malloc would be new byte[size], but that returns you a strongly typed object that you can ONLY use as a byte array.
C free releases a heap node.
Java does not allow you to explicitly release objects. Object deallocation in Java is totally in the hands of the garbage collector. In some cases you can influence the behaviour of the GC; e.g. by assigning null to a reference variable and calling System.gc(). However, this does not force the object to be deallocated ... and is a very expensive way to proceed.
If you are up to no good (tm) I suppose you can get access to raw memory though the JNI interface. This is where you can call C programs from Java Programs. Of course you have to be running in an environment where your program has the privileges to do so (a browser won't normally allow this unless it is suicidal) but you can access objects via C pointers that way.
I sort of wonder where the original question is coming from. At one point long ago I was totally skeptical of the notion that C-style memory management and C-style pointers were not needed, but at this point I am true believer.

why use Heap Memory in Java

Why do we use Heap Memory, Can we use Stack memory for the same?
EDITED
One more question came in my mind after reading answers
1) is there any other kind of memory which we can think of alternative to Heap and Stack?
Edited
I came across the string pool, is that memory associated with the heap or Stack?
Well, you have to use the heap if you want to use objects. Objects are inherently pointers on the stack (or inside other objects) to memory chunks in the heap.
Unlike C++ where you can put objects on the stack or heap, Java does things differently.
Even in C++, it's a good idea to use the heap for objects that must outlive the function they were created in. You probably can avoid it but you may find yourself with a performance problem with all the copy constructors.
As to your edit:
Is there any other kind of memory which we can think of alternative to Heap and Stack?
Sure there is: Static data members, the ones where there's only one per class rather than one per instantiated object must go somewhere. These can't be on the stack since they may disappear when you exit from a function. And they can't belong to an particular object.
These (at least in the Sun/Oracle JVM) go into the Method area.
In addition, you should not think of there being one stack. Every thread gets its own stack on creation.
There's also the runtime constant pool and stacks for native (non-Java) calls.
There's lots of information on the JVM internals here regarding that aspect but keep in mind there may be a distinction between the logical machine and the implementation.
Heap memory is central to Java. All objects are allocated on the heap, and local variables hold only references (essentially pointers) to them. C# allows you to have objects (value types) that live on the stack. Java chose not to borrow this from C++, partly in order to simplify the language.
Across languages, heap memory is the way to provide long-lived objects of arbitrary size.
Can we use Stack memory for the same?
Basically no.
In Java, stack memory is used solely for parameters and local variables of methods (and some hidden book-keeping info which is not relevant to this discussion). And for those variables, only primitive types use just stack memory. Any object or array is represented as a reference to something on the heap, and Java provides no way to allocate an object or array on the stack.
[Aside: it is theoretically possible to perform any calculation in Java using just primitive types and recursive static methods. However, it would be horribly messy. Even writing a simple message to the console will entail your application causing objects to be allocated on the heap. So we can dismiss this as being totally impractical.]
In the JVM, instead of a thread local stack for objects it uses a Thread Local Allocation Buffer or (TLAB) This gives much of the performance benifits of a Stack, without the developer needing to worry about wether an object is on the stack or not.
Heap memory is used to store objects in Java. No matter, where object is created in code.
e.g. as member variable, local variable or class variable, they are always created inside heap space in Java.
If there is no memory left in stack for storing function call or local variable, JVM will throw java.lang.StackOverFlowError,
While if there is no more heap space for creating object, JVM will throw
java.lang.OutOfMemoryError Java Heap Space.
Another important factor to consider is scoping. If all objects were to be allocated on stack then they go out of context as stack frame gets rolled out. In layman terms, think of stack as a dump that stores all the variable values and object references that are local to a subroutine/method which is currently in scope. As soon as it finishes executing (or the method goes out of scope), then all in it would be lost.
It makes it easier for compiler to manage large &/or dynamic sized variables too- they still take small constant storage on call stack- that of 4 bytes ( a heap pointer).

Categories