Chinaunix首页 | 论坛 | 博客
  • 博客访问: 515581
  • 博文数量: 99
  • 博客积分: 2030
  • 博客等级: 大尉
  • 技术积分: 783
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-12 09:11
文章分类

全部博文(99)

文章存档

2023年(2)

2022年(1)

2020年(1)

2019年(1)

2018年(4)

2017年(16)

2016年(60)

2015年(1)

2013年(3)

2006年(10)

我的朋友

分类: Java

2016-03-31 23:13:46

Sometime back I wrote a couple of posts about Java Garbage Collection and Java is Pass by Value, after that I got a lot of emails to explain about Java Heap MemoryJava Stack Memory and what are the differences between them.

You will see a lot of reference to Heap and Stack memory in Java, Java EE books and tutorials but hardly complete explanation of what is heap and stack memory in terms of a program.

Java Heap(堆) Memory

Heap memory is used by java runtime to allocate memory to Objects and JRE classes. Whenever we create any object, it’s always created in the Heap space. Garbage Collection runs on the heap memory to free the memory used by objects that doesn’t have any reference. Any object created in the heap space has global access and can be referenced from anywhere of the application.
堆内存是由java运行时用来分配内存的对象和类的JRE。每当我们创建任何对象时,它总是在堆空间中创建。垃圾收集运行在堆内存中,当一个对象没有引用时,将被释放它对应的内存。在堆空间中创建的任何对象都具有全局访问,并且可以从应用程序的任何地方引用。

Java Stack(栈) Memory

Java Stack memory is used for execution of a thread. They contain method specific values that are short-lived and references to other objects in the heap that are getting referred from the method. Stack memory is always referenced in LIFO (Last-In-First-Out) order.
Whenever a method is invoked, a new block is created in the stack memory for the method to hold local primitive values and reference to other objects in the method. As soon as method ends, the block becomes unused and become available for next method.
Stack memory size is very less compared to Heap memory.

Java 栈内存是执行一个线程时使用的。They contain method specific values that are short-lived and references to other objects in the heap that are getting referred from the method. 栈内存总是LIFO(后进先出)。
无论何时当一个方法被调用时,一个新的内存块在栈内被建立起来给这个方法使用,用于保存局部变量值和在次方法中引用的其它对象。
当方法结束时,该块将的无用并可以被下一个方法使用这块内存。
栈内存大小远小于堆的内存大小。

Let’s understand the Heap and Stack memory usage with a simple program.

package com.journaldev.test;

public class Memory {

	public static void main(String[] args) { // Line 1
		int i=1; // Line 2
		Object obj = new Object(); // Line 3
		Memory mem = new Memory(); // Line 4
		mem.foo(obj); // Line 5
	} // Line 9

	private void foo(Object param) { // Line 6
		String str = param.toString(); //// Line 7
		System.out.println(str);
	} // Line 8

}

Below image shows the Stack and Heap memory with reference to above program and how they are being used to store primitive, Objects and reference variables.存储原始、对象和引用变量。

Let’s go through the steps of execution of the program.

  • As soon as we run the program, it loads all the Runtime classes into the Heap space. When main() method is found at line 1, Java Runtime creates stack memory to be used by main() method thread.
  • 当我们运行这个程序,它将所有的运行时类加载到堆空间中。当main()方法是在1行发现,java虚拟机创建将被main()方法线程使用的栈内存。
  • We are creating primitive local variable at line 2, so it’s created and stored in the stack memory of main() method.
  • 在程序的第2行,我们正在创造原始的局部变量,所以它的创建并存储在main()方法的栈内存中。
  • Since we are creating an Object in line 3, it’s created in Heap memory and stack memory contains the reference for it. Similar process occurs when we create Memory object in line 4.
  • 当我们在3行创建一个对象时,它是在堆内存和栈内存中创建的,包含了它的引用。类似的过程发生在我们在4行创建内存对象时。
  • Now when we call foo() method in line 5, a block in the top of the stack is created to be used by foo() method. Since Java is pass by value, a new reference to Object is created in the foo() stack block in line 6.
  • 现在我们在第五行调用了foo()方法,在栈的顶部一个新的栈块被创建,将被foo()方法使用。由于java是按值传递参数,对象的一个新的引用到Objec被创建到foo()的栈块内,在程序的第6行。
  • A string is created in line 7, it goes in the String Pool in the heap space and a reference is created in the foo() stack space for it.
  • 一个字符串在7行被创建,它在字符串池中的堆空间,在foo()栈空间中一个引用被创建,用于指向这个字符串池
  • foo() method is terminated in line 8, at this time memory block allocated for foo() in stack becomes free.
  • foo()方法是终止在程序第8行,此时分配给foo()栈的内存块变得自由。
  • In line 9, main() method terminates and the stack memory created for main() method is destroyed. Also the program ends at this line, hence Java Runtime frees all the memory and end the execution of the program.
  • 在第9行,main()方法终止,为main()方法创建的栈内存也被销毁。同时程序结束在这一行,因此java运行时释放所有内存,结束程序的执行。

Difference between Heap and Stack Memory


  • Based on the above explanations, we can easily conclude following differences between Heap and Stack memory.Heap memory is used by all the parts of the application whereas stack memory is used only by one thread of execution.


   堆内存是被整个程序各个部分使用,而栈内存只被一个执行的线程使用。
  • Whenever an object is created, it’s always stored in the Heap space and stack memory contains the reference to it. Stack memory only contains local primitive variables and reference variables to objects in heap space.
每当一个对象被创建时,它总是存储在堆空间和堆栈的内存中,包含了它的引用。栈内存中只包含本地的原始变量和引用变量在堆空间中的对象。
  • Objects stored in the heap are globally accessible whereas stack memory can’t be accessed by other threads.
存储在堆中的对象是全局访问的,而栈内存不能被其他线程访问。
  • Memory management in stack is done in LIFO manner whereas it’s more complex in Heap memory because it’s used globally. Heap memory is divided into Young-Generation, Old-Generation etc, more details at Java Garbage Collection.
在栈内存管理是后进先出的方式进行,而在堆内存的更复杂,因为它是全局使用。堆内存分为年轻的一代,老一代等,更多的细节在java的垃圾收集
  • Stack memory is short-lived whereas heap memory lives from the start till the end of application execution.
栈内存是短暂的,而堆内存的生命从开始到应用程序结束。
  • We can use -Xms and -Xmx JVM option to define the startup size and maximum size of heap memory. We can use -Xss to define the stack memory size.
我们可以使用-Xms和-Xmx选项启动JVM定义大小和堆内存的最大尺寸。我们可以使用XSS定义栈的内存大小。
  • When stack memory is full, Java runtime throws java.lang.StackOverFlowError whereas if heap memory is full, it throws java.lang.OutOfMemoryError: Java Heap Space error.
当栈内存已满,java运行时抛出java.lang.stackoverflowerror
如果堆内存已满,把java.lang.outofmemoryerror:Java Heap Space error.
  • Stack memory size is very less when compared to Heap memory. Because of simplicity in memory allocation (LIFO), stack memory is very fast when compared to heap memory.
栈内存大小与堆内存相比要少多。因为在内存分配的简单(LIFO),栈内存比堆内存快的多。

That’s all for Stack vs Heap Memory in terms of java application, I hope it will clear your doubts regarding memory allocation when any java program is executed.

I have made a video tutorial for this, you should watch it to clarify any doubts.

阅读(1434) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~