Java中堆和栈的区别详解_java

当一个人开始学习Java或者其他编程语言的时候,会接触到堆和栈,由于一开始没有明确清晰的说明解释,很多人会产生很多疑问,什么是堆,什么是栈,堆和栈有什么区别?更糟糕的是,Java中存在栈这样一个后进先出(Last In First Out)的顺序的数据结构,这就是java.util.Stack。这种情况下,不免让很多人更加费解前面的问题。事实上,堆和栈都是内存中的一部分,有着不同的作用,而且一个程序需要在这片区域上分配内存。众所周知,所有的Java程序都运行在JVM虚拟机内部,我们这里介绍的自然是JVM(虚拟)内存中的堆和栈。

区别

java中堆和栈的区别自然是面试中的常见问题,下面几点就是其具体的区别

各司其职

最主要的区别就是栈内存用来存储局部变量和方法调用。
而堆内存用来存储Java中的对象。无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中。

独有还是共享

栈内存归属于单个线程,每个线程都会有一个栈内存,其存储的变量只能在其所属线程中可见,即栈内存可以理解成线程的私有内存。
而堆内存中的对象对所有线程可见。堆内存中的对象可以被所有线程访问。

异常错误

如果栈内存没有可用的空间存储方法调用和局部变量,JVM会抛出java.lang.StackOverFlowError。
而如果是堆内存没有可用的空间存储生成的对象,JVM会抛出java.lang.OutOfMemoryError。

空间大小

栈的内存要远远小于堆内存,如果你使用递归的话,那么你的栈很快就会充满。如果递归没有及时跳出,很可能发生StackOverFlowError问题。
你可以通过-Xss选项设置栈内存的大小。-Xms选项可以设置堆的开始时的大小,-Xmx选项可以设置堆的最大值。

这就是Java中堆和栈的区别。理解好这个问题的话,可以对你解决开发中的问题,分析堆内存和栈内存使用,甚至性能调优都有帮助。

查看默认值(Updated)

查看堆的默认值,使用下面的代码,其中InitialHeapSize为最开始的堆的大小,MaxHeapSize为堆的最大值。

复制代码 代码如下:

13:17 $ java -XX:+PrintFlagsFinal -version | grep HeapSize
    uintx ErgoHeapSizeLimit                         = 0                                   {product}
    uintx HeapSizePerGCThread                       = 87241520                            {product}
    uintx InitialHeapSize                          := 134217728                           {product}
    uintx LargePageHeapSizeThreshold                = 134217728                           {product}
    uintx MaxHeapSize                              := 2147483648                          {product}
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

查看栈的默认值,其中ThreadStackSize为栈内存的大小。

复制代码 代码如下:

13:21 $ java -XX:+PrintFlagsFinal -version | grep ThreadStackSize
     intx CompilerThreadStackSize                   = 0                                   {pd product}
     intx ThreadStackSize                           = 1024                                {pd product}
     intx VMThreadStackSize                         = 1024                                {pd product}
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)

译文信息

原汁原味的英文原文:http://javarevisited.blogspot.com.au/2013/01/difference-between-stack-and-heap-java.html.

译文在原文基础上进行了修改,整理,删减。如有兴趣可以访问原文。P.S.地址已被墙。

时间: 2025-01-19 05:21:10

Java中堆和栈的区别详解_java的相关文章

Java中Vector与ArrayList的区别详解_java

首先看这两类都实现List接口,而List接口一共有三个实现类,分别是ArrayList.Vector和LinkedList.List用于存放多个元素,能够维护元素的次序,并且允许元素的重复.3个具体实现类的相关区别如下:1.ArrayList是最常用的List实现类,内部是通过数组实现的,它允许对元素进行快速随机访问.数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要讲已经有数组的数据复制到新的存储空间中.当从ArrayList的中间位置插入或者删除元素时,需要对数组

Java中堆与栈的区别

栈与堆都是Java用来在RAM中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new.newarray.anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放.堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据.但缺点是,由于要在运行时动态分配

Java中一些基础概念的使用详解_java

类的初始化顺序 在Java中,类里面可能包含:静态变量,静态初始化块,成员变量,初始化块,构造函数.在类之间可能存在着继承关系,那么当我们实例化一个对象时,上述各部分的加载顺序是怎样的? 首先来看代码: 复制代码 代码如下: class Parent {     public static StaticVarible staticVarible= new StaticVarible("父类-静态变量1");         public StaticVarible instVaribl

java中哈希表及其应用详解_java

哈希表也称为散列表,是用来存储群体对象的集合类结构. 什么是哈希表 数组和向量都可以存储对象,但对象的存储位置是随机的,也就是说对象本身与其存储位置之间没有必然的联系.当要查找一个对象时,只能以某种顺序(如顺序查找或二分查找)与各个元素进行比较,当数组或向量中的元素数量很多时,查找的效率会明显的降低. 一种有效的存储方式,是不与其他元素进行比较,一次存取便能得到所需要的记录.这就需要在对象的存储位置和对象的关键属性(设为 k)之间建立一个特定的对应关系(设为 f),使每个对象与一个唯一的存储位置

JAVA中的final关键字用法实例详解_java

本文实例讲述了JAVA中的final关键字用法.分享给大家供大家参考,具体如下: 根据上下文环境,java的关键字final也存在着细微的区别,但通常指的是"这是无法改变的."不想改变的理由有两种:一种是效率,另一种是设计.由于两个原因相差很远,所以关键子final可能被误用. 接下来介绍一下使用到final的三中情况:数据,方法,类 final数据 许多编程语言都有某种方法,来向编译器告知一块数据是恒定不变的.有时数据的恒定不变是很有用的,例如: 1. 一个编译时恒定不变的常量 2.

Java中自然排序和比较器排序详解_java

前言 当指执行插入排序.希尔排序.归并排序等算法时,比较两个对象"大小"的比较操作.我们很容易理解整型的 i>j 这样的比较方式,但当我们对多个对象进行排序时,如何比较两个对象的"大小"呢?这样的比较 stu1 > stu2 显然是不可能通过编译的.为了解决如何比较两个对象大小的问题,JDK提供了两个接口 java.lang.Comparable 和 java.util.Comparator . 一.自然排序:java.lang.Comparable C

java集合——Java中的equals和hashCode方法详解_java

Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法,今天就来介绍一些这两个方法的作用. equals()和hashCode()方法是用来在同一类中做比较用的,尤其是在容器里如set存放同一类对象时用来判断放入的对象是否重复. 这里我们首先要明白一个问题: equals()相等的两个对象,hashcode()一定相等,equals()不相等的两个对象,却并不能证明他们的hashcode()不相等.换

Java中FilterInputStream和FilterOutputStream的用法详解_java

FilterInputStream FilterInputStream 的作用是用来"封装其它的输入流,并为它们提供额外的功能".它的常用的子类有BufferedInputStream和DataInputStream. BufferedInputStream的作用就是为"输入流提供缓冲功能,以及mark()和reset()功能". DataInputStream 是用来装饰其它输入流,它"允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类

java中Struts2文件上传问题详解_java

首先是网页部分,upload_file.jsp <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML> <html> <head> <title>Upload File</title> </head> <body> <form act