Fetch Windows OS, System, Memory, BIOS, Network, Hard Drive details using Java code

Fetch Windows System details

In lot of applications or real time programs we may in need of finding the Windows system information's like

1. Windows system properties like fetching Windows OS version, JVM version, OS architecture, Java Version, OS name, Windows user name etc.,
2. Fetching Windows BIOS serial number.
3. Fetching memory details like 

  • Virtual Memory Size 
  • Free Physical Memory Size 
  • Free Swap Space Size 
  • Process CPU Time 
  • Total Physical Memory Size 
  • Total Swap Space Size 

4. Fetching network interface and Adapter details 
5. Fetching system hard drive details like each drive total and free space. 

Lets see a Java code which will fetch a complete information as we discussed above.


import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.reflect.Method;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.Scanner;

public class FindWindows {

 public static void main(String[] args) {
  
  System.out.println("\n *********************** SYSTEM DETAILS ***********************  ");
  systemDetails();
  System.out.println("\n *********************** MEMORY DETAILS ***********************  ");
  getMemoryDetails();
  System.out.println("\n *********************** BIOS SERIAL NUMBER ***********************  ");
  getBIOSSerialNumber();
  System.out.println("\n *********************** NETWORK DETAILS ***********************  ");
  getNetworkDetails();
  System.out.println("\n *********************** HARD DRIVE DETAILS ***********************  ");
  getHardDriveDetails();
 }

 public static void systemDetails() {
  System.getProperties().list(System.out);
 }

 private static void getMemoryDetails() {
  
  OperatingSystemMXBean osMemDetails = ManagementFactory
    .getOperatingSystemMXBean();
  
  for (Method method : osMemDetails.getClass().getDeclaredMethods()) {
   method.setAccessible(true);
   long value = 0;
   try {
    value = method.invoke(osMemDetails) != null ? Long
      .parseLong(method.invoke(osMemDetails).toString()) : 0;
   } catch (Exception e) {
    e.printStackTrace();
   }
   
   System.out.println(method.getName() + " : " + value+" Bytes");
  }
  
  // no. of processors available
     System.out.println("No. of processors : " + Runtime.getRuntime().availableProcessors());
 }

 public static void getBIOSSerialNumber() {
  try{
   Process process = Runtime.getRuntime().exec(
     new String[] { "wmic", "bios", "get", "serialnumber" });
   
   process.getOutputStream().close();
   Scanner sc = new Scanner(process.getInputStream());
   String property = sc.next();
   String serial = sc.next();
   
   System.out.println(property + ": " + serial);
  }catch (IOException e) {
   e.printStackTrace();
  }
 }

 public static void getNetworkDetails() {
  try{
   Enumeration<NetworkInterface> netIntList = NetworkInterface
     .getNetworkInterfaces();
   while (netIntList.hasMoreElements()) {
    NetworkInterface netInt = netIntList.nextElement();
    System.out.println(netInt.getName() + " : " + netInt.getDisplayName());
   }
  }catch (IOException e) {
   e.printStackTrace();
  }
 }

 public static void getHardDriveDetails() {
  File[] drives = File.listRoots();
  for (int i = 0; i < drives.length; i++) {
   System.out.println("Drive :" + drives[i]);
   File drive = new File(drives[i].toString());
   long totalDriSpace = drive.getTotalSpace();
   long freeSpace = drive.getFreeSpace();
   
   totalDriSpace = (totalDriSpace/1024/1024/1024); // Converting Bytes to GB
   freeSpace = (freeSpace/1024/1024/1024); // Converting Bytes to GB
   
   System.out.println("Total Drive Size : " + totalDriSpace+" GB");
   System.out.println("Free Space       : " + freeSpace+" GB");
   System.out.println("-------------------------------------");
  }
 }
}


OUTPUT:


 *********************** SYSTEM DETAILS ***********************  
-- listing properties --
java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=C:\Program Files\Java\jre6\bin
java.vm.version=16.3-b01
java.vm.vendor=Sun Microsystems Inc.
java.vendor.url=http://java.sun.com/
path.separator=;
java.vm.name=Java HotSpot(TM) Client VM
file.encoding.pkg=sun.io
user.country=US
sun.java.launcher=SUN_STANDARD
sun.os.patch.level=Service Pack 1
java.vm.specification.name=Java Virtual Machine Specification
user.dir=D:\workspace\java\MyProject
java.runtime.version=1.6.0_20-b02
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs=C:\Program Files\Java\jre6\lib\endorsed
os.arch=x86
java.io.tmpdir=C:\Users\anand\AppData\Local\Temp\
line.separator=

java.vm.specification.vendor=Sun Microsystems Inc.
user.variant=
os.name=Windows 7
sun.jnu.encoding=Cp1252
java.library.path=C:\Program Files\Java\jre6\bin;.;C:\W...
java.specification.name=Java Platform API Specification
java.class.version=50.0
sun.management.compiler=HotSpot Client Compiler
os.version=6.1
user.home=C:\Users\anand
user.timezone=
java.awt.printerjob=sun.awt.windows.WPrinterJob
file.encoding=Cp1252
java.specification.version=1.6
user.name=anand
java.class.path=D:\workspace\java\MyProject\bin;D:\wo...
java.vm.specification.version=1.0
sun.arch.data.model=32
java.home=C:\Program Files\Java\jre6
java.specification.vendor=Sun Microsystems Inc.
user.language=en
awt.toolkit=sun.awt.windows.WToolkit
java.vm.info=mixed mode, sharing
java.version=1.6.0_20
java.ext.dirs=C:\Program Files\Java\jre6\lib\ext;C:...
sun.boot.class.path=C:\Program Files\Java\jre6\lib\resour...
java.vendor=Sun Microsystems Inc.
file.separator=\
java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport...
sun.cpu.endian=little
sun.io.unicode.encoding=UnicodeLittle
sun.desktop=windows
sun.cpu.isalist=pentium_pro+mmx pentium_pro pentium+m...

 *********************** MEMORY DETAILS ***********************  
getCommittedVirtualMemorySize : 41385984 Bytes
getCommittedVirtualMemorySize0 : 41385984 Bytes
getFreePhysicalMemorySize : 794828800 Bytes
getFreeSwapSpaceSize : 4186632192 Bytes
getProcessCpuTime : 93600600 Bytes
getTotalPhysicalMemorySize : 2147483647 Bytes
getTotalSwapSpaceSize : 4294967295 Bytes
initialize : 0 Bytes
No. of processors : 2

 *********************** BIOS SERIAL NUMBER ***********************  
SerialNumber: 993D1BS

 *********************** NETWORK DETAILS ***********************  
lo : Software Loopback Interface 1
net0 : WAN Miniport (SSTP)
net1 : WAN Miniport (L2TP)
net2 : WAN Miniport (PPTP)
ppp0 : WAN Miniport (PPPOE)
eth0 : WAN Miniport (IPv6)
eth1 : WAN Miniport (Network Monitor)
eth2 : WAN Miniport (IP)
ppp1 : RAS Async Adapter
eth3 : Intel(R) 82567LM Gigabit Network Connection
net3 : Teredo Tunneling Pseudo-Interface
net4 : Intel(R)  WiFi Link 5300 AGN
eth4 : WAN Miniport (IP) - Juniper Network Agent Miniport
eth5 : Intel(R)  WiFi Link 5300 AGN - Juniper Network Agent Miniport
net5 : Juniper Networks Virtual Adapter Manager
eth6 : Juniper Networks Virtual Adapter
eth7 : Juniper Networks Virtual Adapter - Juniper Network Agent Miniport
eth8 : Juniper Networks Virtual Adapter #2
eth9 : Juniper Networks Virtual Adapter #2 - Juniper Network Agent Miniport
eth10 : Juniper Networks Virtual Adapter #3
eth11 : Juniper Networks Virtual Adapter #3 - Juniper Network Agent Miniport
eth12 : Juniper Networks Virtual Adapter #4
eth13 : Juniper Networks Virtual Adapter #4 - Juniper Network Agent Miniport
net6 : WAN Miniport (IKEv2)
eth14 : Juniper Network Connect Virtual Adapter
eth15 : Juniper Network Connect Virtual Adapter - Juniper Network Agent Miniport
net7 : Microsoft 6to4 Adapter
net8 : Microsoft ISATAP Adapter
net9 : Microsoft ISATAP Adapter #3
net10 : Microsoft ISATAP Adapter #2
net11 : Microsoft ISATAP Adapter #4
eth16 : Intel(R) 82567LM Gigabit Network Connection-QoS Packet Scheduler-0000
eth17 : Intel(R) 82567LM Gigabit Network Connection-WFP LightWeight Filter-0000
eth18 : Intel(R)  WiFi Link 5300 AGN - Juniper Network Agent Miniport-QoS Packet Scheduler-0000
eth19 : Intel(R)  WiFi Link 5300 AGN - Juniper Network Agent Miniport-WFP LightWeight Filter-0000
eth20 : WAN Miniport (Network Monitor)-QoS Packet Scheduler-0000
eth21 : Juniper Network Connect Virtual Adapter - Juniper Network Agent Miniport-QoS Packet Scheduler-0000
eth22 : WAN Miniport (IPv6)-QoS Packet Scheduler-0000
net12 : Intel(R)  WiFi Link 5300 AGN-Native WiFi Filter Driver-0000
eth23 : Juniper Network Connect Virtual Adapter - Juniper Network Agent Miniport-WFP LightWeight Filter-0000
eth24 : WAN Miniport (IP) - Juniper Network Agent Miniport-QoS Packet Scheduler-0000

 *********************** HARD DRIVE DETAILS ***********************  
Drive :C:\
Total Drive Size : 68 GB
Free Space       : 27 GB
-------------------------------------
Drive :D:\
Total Drive Size : 80 GB
Free Space       : 72 GB
-------------------------------------
Drive :E:\
Total Drive Size : 0 GB
Free Space       : 0 GB
-------------------------------------
Drive :H:\
Total Drive Size : 4191 GB
Free Space       : 113 GB
-------------------------------------
Drive :M:\
Total Drive Size : 78 GB
Free Space       : 48 GB
-------------------------------------
Drive :N:\
Total Drive Size : 78 GB
Free Space       : 48 GB
-------------------------------------

How to read webpage source code through Java?

We might be seeing "view page source" option in all web browsers. Just by right click and by selecting "view page source" it will give us the complete client side source code of that particular page. So how we can get this done by using Java code? For this we need to use URLConnection class which establish the connection to the server and next by using InputStream class we can read complete page content as bytes. 

Next by iterating InputStream instance (byte by byte) we can get the complete page source as bytes and we can store it in a file for our reference. Lets see simple example to read web page source code through Java.


import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

public class URLReader {
 
 public static void main(String[] args) {
  try{
   URL url = new URL("http://docs.oracle.com/javase/6/docs/api/java/net/URLConnection.html");
   URLConnection urlCon = url.openConnection();
   InputStream is = urlCon.getInputStream();
   
   File myFile = new File("C://URLConnection.html");
   if(!(myFile.exists())){ 
             myFile.createNewFile();
   }
   
   FileWriter fWrite = new FileWriter(myFile, true);  
         BufferedWriter bWrite = new BufferedWriter(fWrite); 
   int i=0;
   while((i=is.read()) != -1){
       bWrite.write((char)i); 
   }

   bWrite.close();
   System.out.println("Web page reading completed...");
   
  }catch (Exception e) {
   e.printStackTrace();
  } 
  
 }
}


OUTPUT:
read webpage source code through Java

read webpage source code through Java



wait(), notify(), notifyAll() in Java

 
When we come to multi-threading environment then we need of some communication between each thread like some thread has to perform task after other thread completes its task. In other way some thread has to communicate to other thread that you can takeover the Object monitor from waiting state. Basically we can say its a inter thread communication. For this we can use these methods very effectively and it does the same work for us. 

All these methods are used in Java Multi-threading and used to communicate between each threads under same Object. Just by name itself we can assume that wait() makes the thread to wait or halt for some time, notify() and notifiAll() used to indicate other threads. Lets see each one by briefly and what is the use in multi-threading. 

wait()
Makes current thread to wait and release the lock which acquired on the Object and waits for the other thread to call notify() or notifyAll() method. At the time of waiting other thread will does his process and communicate to waiting threading by calling notify or notifyAll method. One notify or notifyAll method called waiting thread will acquire the lock and it continues the process. There are 2 types of wait() methods in Java and they are 

  • wait() - Waits until other thread calls notify or notifyAll method. This method throws InterruptedException
  • wait(long milliseconds) - Waits up-to given milliseconds and it starts the process. This method also throws InterruptedException.

notify()
Once notify() called it makes waiting thread to acquire the Object and it starts the process. Suppose if more threads are waiting for the Object to acquire then any one thread will be acquire the Object monitor and the choice is arbitrary. 

notifyAll()
Once notifyAll() method called it wake-up all threads that are waiting the Objects monitor. So the difference between notify() and notifyAll() is simple that once notify() method called only one thread will wake-up and by notifyAll() method all waiting threads will go to runnable state. 

Next lets see simple example for using wait() and notify() with perfect example of amount deposit and withdraw from bank. Suppose when we withdrawing the amount if the balance is insufficient then the thread has to wait for deposit thread and then we need to withdraw the amount. For this we will be using wait() in withdraw thread and notify() in deposit thread.


public class BankTrans implements Runnable {
 
 private int amount = 0;
 
 @Override
 public synchronized void run() {
  if(Thread.currentThread().getName().equals("withdraw")){
   System.out.println("Entering to withdraw amount");
   //Trying to withdraw 5000
   if(this.amount >= 5000){
    this.amount -= 5000;
   }else{
    try {
     System.out.println("Insufficient balance and waiting for deposit....");
     wait();
     this.amount -= 5000; 
     System.out.println("Amount withdraw completed successfully :)");
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }else{
   //Depositing 10000 in user account;
   System.out.println("Entering to deposit amount");
   this.amount += 10000;
   System.out.println("Amount deposited and notifying....");
   notify();
  }
 }
 
 public static void main(String[] args) {
  BankTrans obj = new BankTrans();
  Thread withDraw = new Thread(obj, "withdraw");
  Thread deposit = new Thread(obj, "deposit");
  withDraw.start();
  deposit.start();
 }
}


OUTPUT:


Entering to withdraw amount
Insufficient balance and waiting for deposit....
Entering to deposit amount
Amount deposited and notifying....
Amount withdraw completed successfully :)





What is Marker Interface in Java?

Marker interfaces are special interfaces in Java. Marker interface will not have any methods or member variables. Just declared with interface name and also called as Tag interface. 

Then what is the use of Marker interface in Java?
Normally interface used to tell compiler about the behavior of the class. Used to tag the implementation of class based on their purpose and behavior. Just used to "mark" the java class which support a certain capability.

Alternate for Marker or Tag interfaces?
Java 1.5 came up with Annotations as an alternate solution for Marker interfaces. Advantage of using annotations are just it makes loose coupling instead of implementing marker interfaces. 
By using Annotations we can easily specify special behavior to the class but it can't act as the super type of the class what we can achieve by Marker interface. 

Is there any Marker interfaces provided by Java?
Below are the list of marker interfaces provided by Java

  • Cloneable
  • Serializable
  • EventListener
  • RandomAccess
  • SingleThreadModel
  • Remote

Advantage of using Marker interface?
Apart from using Java built-in Marker interfaces, we can also create our own Marker interfaces for our application specific needs like classify code, logically to divide the code which does its own process at run-time. For example when we go for API or framework development Marker interface plays the important role like we have in Spring, Struts etc.,

Lets see simple example of using Marker interface in Java


public interface MyMarker {
 // Marker interface without any methods or variables 
}



public class MyMarkerTest implements MyMarker {
 
 public static void main(String[] args) {
  
  MyMarkerTest obj = new MyMarkerTest();
  
  if (obj instanceof MyMarker) {
   System.out.println("obj is an instance of MyMarker");
  } else {
   System.out.println("obj is NOT an instance of MyMarker");
  }
 }
}


OUTPUT:


obj is an instance of MyMarker




What is Covariant return types in Java?

While overriding the methods in subclass name, arguments, and return type must me same as super class method until before Java 1.5. Overriding method is said to be invariant with respect to argument types and return type of super class. Suppose if we changing any argument types then its not actually overriding but its method overloading. Complete method signature must be as same as super class method for overriding till before Java 1.5.

This has been relaxed from Java 1.5, where subclass method can have different return type but only condition is subclass can return type must be a sub-type of super-class return type. Lets see simple example for Covariant return types in Java and how it works,


public class ClassA {
 
 public ClassA getInstance(){
  return new ClassA();
 }
 
 public void sayHello(){
  System.out.println("Hello Class A ");
 }
}



public class ClassB extends ClassA{
 
 @Override
 public ClassB getInstance() {
  return new ClassB();
 }
 
 @Override
 public void sayHello() {
  System.out.println("Hello Class B ");
 }
 
 public static void main(String[] args) {
  ClassA obj = new ClassB().getInstance();
  obj.sayHello();
 }
}


OUTPUT:


Hello Class B 



If we seen in above example we are overriding getInstance() method from super class ClassA. But the return type is different from super class method where we are returning subclass instance here. Even though we are overriding return types are different in both the methods. This is called as Covariant return types in Java.

By this we can remember that from Java 1.5 overriding method can different return type with single condition ie., subclass can return type must be a sub-type of super-class return type.






How to convert list to read-only list in Java?

 
By using Collections class we can convert List to read-only List. This can done by using Collections.unmodifiableList(list) function from Collections class. By this we can't add or remove any element from the List. Not only List we can make other Collection Objects like Map, Set also to read-only as like below.

Collections.unmodifiableMap(map);
Collections.unmodifiableSet(set);
Collections.unmodifiableSortedMap(sortedMap);
Collections.unmodifiableSortedSet(sortedSet);

Lets see small example how to convert list to read-only list.


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ReadOnlyList {

 public static void main(String[] args) {
  
  List<String> list = new ArrayList<String>();
  list.add("java");
  list.add("discover");
  list.add("threads");
  list.add("oops");
  list.add("servlet");
  
  System.out.println("LIST : "+list);
  
  // Removing "oops" from from list
  list.remove(3);
  
  System.out.println("LIST : "+list);
    
  // Making list to read-only
  list = Collections.unmodifiableList(list);

  // trying to removing "threds" from list
  list.remove(2);
    
  System.out.println("LIST : "+list);
 }
}


OUTPUT:


LIST : [java, discover, threads, oops, servlet]
LIST : [java, discover, threads, servlet]
Exception in thread "main" java.lang.UnsupportedOperationException


If we seen in above program we have added 5 values in list and we have removed 1 value "oops" from the list. Next we have converted list to read-only list by using unmodifiableList() method. Later when we try to remove "discover" value it throws UnsupportedOperationException because of read-only list. Even we can't add any value to this list. 




Daemon Thread in Java

 
Basically in Java there are 2 types of threads and they are Daemon Thread and non-Daemon Thread (User threads). Daemon threads are nothing but service provider for other threads to perform their task under same process like Garbage collection etc., Any Java thread can be a daemon thread and daemon threads life depends on user threads. It will be alive until all other threads are running and JVM will terminate daemon thread automatically once all other threads died. Some of the points to be remembered about daemon thread are 

  • Daemon threads are low priority threads. 
  • Daemon threads life depends on all other user threads (non-daemon threads) in same process.
  • Finally it provides only service to other user threads and nothing more than that.  
  • To specify the thread as daemon thread, just call the setDaemon method with the argument "true"  like  ( Thread.setDaemon(true) ).
  • Setting daemon should be done before starting the Thread, else it will throw IllegalThreadStateException exception. 
  • JVM will automatically exit the process once all user threads are completed and it won't wait for any Daemon thread to complete, no matter how many Daemon threads are running. 

Lets see small example with creating Daemon Thread and user threads under same process and lets see how its work.


public class DaemonThreadTest extends Thread{
 
 String daemonFlag = "";
 
 public DaemonThreadTest() { }
 
 public DaemonThreadTest(String daemonFlag) {
  this.daemonFlag = daemonFlag;
 }
 
 public void run() {
  if(daemonFlag.equals("daemon")){
   while(true){    
    try {
     System.out.println("Daemon Thread Running !!!");
     Thread.sleep(500);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }else{
   for(int i=0;i<5;i++){
    try {
     System.out.println("User Thread Running !");
     Thread.sleep(500);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }
 }
 
 public static void main(String args[]){
    
  DaemonThreadTest daemonThread = new DaemonThreadTest("daemon");
  DaemonThreadTest userThread1 = new DaemonThreadTest();
  DaemonThreadTest userThread2 = new DaemonThreadTest();
  
  // Setting Daemon thread;
  daemonThread.setDaemon(true);
  
  daemonThread.start();
  userThread1.start();
  userThread2.start();
 }
}


OUTPUT:


Daemon Thread Running !!!
User Thread Running !
User Thread Running !
Daemon Thread Running !!!
User Thread Running !
User Thread Running !
Daemon Thread Running !!!
User Thread Running !
User Thread Running !
Daemon Thread Running !!!
User Thread Running !
User Thread Running !
Daemon Thread Running !!!
User Thread Running !
User Thread Running !
Daemon Thread Running !!!

In above sample program we can see Daemon Thread we have set in infinite loop and user threads under looping for 5 times. One all other user thread complete Daemon Thread has be terminated automatically by JVM and process get completed. No more Daemon Thread is running. 

Executing Unix command through Java


In this tutorial we will see about executing Unix command through Java program and printing the output as same as Unix shell command printing. We can achieve by using Process class in Java. 

Process class provides the methods for performing 
standard input from the given process, 
performing standard output to the process, 
waiting for the process to complete its task, 
checking exit status of the process and 
destroying the process (normally its killing the process).

Constructor in Process class:
Process()

Method in Process class:
abstract InputStream getInputStream()
Used to get the standard input stream of sub-process.

abstract OutputStream getOutputStream()
Used to get the standard output stream of the sub-process.

abstract InputStream getErrorStream()
Used to get the standard error stream of the sub-process.

abstract void destroy()
Used to kill the sub-process.

abstract int exitValue()
Returns the exit value for the sub-process.

abstract int waitFor()
Makes current thread to wait, if necessary, until the process represented by this Process object has terminated.


Now lets see about how to execute Unix command using Process class in Java with simple example of listing folder and files from the current Folder. Second output will show you Error Stream result when we try to unzip a file.


import java.io.InputStream;

public class UnixCommandThroughJava {

 public static void main (String args[]) {
     
  String unixCommand = "ls -lh";
     InputStream in = null;
     
     try {
         StringBuilder commandResult = new StringBuilder();
         
         Process p = Runtime.getRuntime().exec(unixCommand, null);
         
         int returnVal = p.waitFor();
         
         if (returnVal == 0){ // no error           
             in = p.getInputStream();
         }else{     // If any error occurred 
             in = p.getErrorStream();
         }
         
         int readInt;
         while ((readInt = in.read()) != -1){
             commandResult.append((char)readInt);                
         }
         
         System.out.println("COMMAND : " + unixCommand + "\n\nOUTPUT : \n" + commandResult.toString());
          
         in.close();
     
     } catch (Exception e) {
         System.out.println("An exception occured while executing command " + unixCommand);
         e.printStackTrace();
     }
 }
}


OUTPUT:


Executing Unix command through Java


Executing Unix command through Java





Heap and Stack in Java

 

We are discussing few interview questions from our earlier tutorials and its a follow-up with same interview questions in Java. Questions are 

How memory managed in java? 
What is Heap and Stack memory? 
What will be stored in Heap and Stack?
Determine the size of Heap and Stack?
Stack vs Heap Pros and Cons?
When to use Heap and Stack?

This is one of the important questions which asked in most of the Java interviews and later interviewer may jump into asking question in Operating System(OS) level memory management also. Lets see above questions one by one and finally its a simple programs where we all can discuss about the memory allocated for it in Java.

How memory managed in Java?
Stack and Heap are the memories allocated by OS to JVM and they both are stored in the computer's RAM (Random Access Memory). 

What is Heap and Stack memory?
Stack:
It's a special region of computer's memory that stores temporary variables created by each functions. Stack uses "FILO" (First In Last Out) data structure, where its managed and optimized by CPU closely.

Heap:
Heap is a region of computer's memory that is not managed automatically by programmer, and is not as tightly managed by the CPU. It is a more free-floating region of memory.


What will be stored in Heap and Stack memory?
Stack:
Methods and the local variables are stored in stack. Also it is to be remembered that the variable references primitive or object references will be stored in Stack.  

Heap:
Objects and its instance variable are stored in Heap. In Java 6 due to "escape analysis" optimization, sometimes objects will be stores in Stack also.


Determine the size of Heap and Stack?
Stack:
Stack is usually pre-allocated and limited in size, because by definition it must be contiguous memory. Also depends on the language, compiler, operating system and architecture. 

Heap:
In general Heap will be dynamically allocated and constantly changing in size. 


Stack vs Heap Pros and Cons?
Stack:
Very fast in access.
Explicitly can't de-allocate variables allocated in Stack.
Memory fragmentation will not happen in Stack, since its managed efficiently by CPU.
Stack size is limited depending on OS.
If Stack runs out of memory, then this leeds to stack overflow could cause program to crash.

Heap:
Slower in access compared to Stack.
No limited on memory size which will be dynamically allocated. 
Heap could cause fragmentation problem, which occurs when memory on the heap is being stored as non-contiguous blocks. 

When to use Heap and Stack?
Its better to choice Stack when we use less memory or small amount of data in usage. Suppose if we don't know about the size or application uses large amount of memory like dynamic array or collections then we need to go for Heap. 


Lets discuss:


public class MyProgram {
 
 private static int value = 10;
 private String str = new String("Java Discover");
 private String name = "Heap and Stack";
 
 public void sayHello(){
  System.out.println("Hello, Java Discover !!!");
 }
 
 public static void main(String[] args) {
  
  String country = "India";
  
  MyProgram obj1;
  
  MyProgram obj2 = new MyProgram();
  obj2.sayHello();
 }
}



Lets comment on the memory usage on above program as what will be stored in Stack and Heap?