您的位置:www.85058.com > 互联网资讯 > Java堆和栈的区别,JVM堆和栈的介绍

Java堆和栈的区别,JVM堆和栈的介绍

发布时间:2019-11-05 10:40编辑:互联网资讯浏览(78)

    一、Java的堆内存和栈内存

    栈内存和堆内存

      栈和堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈和堆。

    Java把内存划分成两种:一种是堆内存,一种是栈内存。

      在函数中定义的一些基本类型的变量对象的引用都是在函数的栈内存中分配。当定义一个变量是,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。栈先进后出,队列先进先出。

      栈的优势是,存取速度比堆快,仅次于直接位于CPU中的寄存器,缺点是,存在栈中的数据大小与生存周期必须是确定的,缺乏灵活性。另外栈数据可以共享。

    堆:主要用于存储实例化的对象,数组,堆是存储的单位,它解决的是数据储存的问题,即数据怎么放,放在哪里。由JVM动态分配内存空间。一个JVM只有一个堆内存,线程是可以共享数据的。

      堆内存用于存放由new创建的对象和数组。在堆分配的内存,由java虚拟机自动垃圾回收器来管理。在数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再次被使用,但是仍占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这也是java比较占内存的主要原因。   

      堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。缺点是要在运行时动态分配内存,存取速度较慢。

     

       http://blog.csdn.net/songjie521/article/details/3368386

      当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法中定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁。因此,所有在方法中定义的局部变量都是放在栈内存中的;

      在程序中创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用(对象创建成本较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,及时方法结束后,这个对象还可能被另一个引用变量所引用,则这个对象依然不会被销毁,只有当一个对象没有任何引用变量引用它时,系统的垃圾回收器才会在合适的时候回收它。

    栈:栈是运行时的单位,它解决程序的运行问题,即程序如何执行,或者说如何处理数据,另外它主要用于存储局部变量和对象的引用变量,每个线程都会有一个独立的栈空间,所以线程之间是不共享数据的。

    方法区

      方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当开发人员在程序中通过Class对象中的getName、isInterface等方法来获取信息时,这些数据都来源于方法区域,同时方法区域也是线程共享的。

    在Java中有一个线程就会相应的有一个线程栈与之对应,因为不同的线程执行的逻辑有所不同,因此需要一个独立的线程栈,而堆则是所有线程共享的。栈因为是运行单位,因此里面储存的信息都是跟当前线程相关的信息。包括局部变量、程序运行状态、方法返回值等等,而堆只负责储存对象的信息。

    区别:

            http://droidyue.com/blog/2014/12/07/differences-between-stack-and-heap-in-java/

      堆和栈都是内存中的一部分,有着不同的作用,而且一个程序需要在这片区域上分配内存。众所周知,所有的Java程序都运行在JVM虚拟机内部,我们这里介绍的自然是JVM(虚拟)内存中的堆和栈。

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

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

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

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

     

    每一个Java应用都唯一对应一个JVM实例,每一个实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放在这个堆中,并由应用所有的线程 共享.跟C/C++不同,Java中分配堆内存是自动初始化的。Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配,也就是说在建立一个对象时从两个地方都分配内存,在堆中分配的内存实际建立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指针而已。

    在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。

    堆内存用来存放由new创建的对象和数组。

    在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。二、栈与堆的共同点和优缺点

    1. 栈与堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。

    2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

    3. 在Java语言中有8种基本类型和一种比较特殊的类型String。这些类型为了使它们在运行过程中速度更快、更节省内存,都提供了一种常量池的概念。常量池就类似一个java系统级别提供的缓存。8种基本类型的常量池都是系统协调的,String类型的常量池比较特殊。

    它的主要使用方法有两种:

    本文由www.85058.com发布于互联网资讯,转载请注明出处:Java堆和栈的区别,JVM堆和栈的介绍

    关键词:

上一篇:没有了

下一篇:没有了