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

一、栈内存

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

Java中的代码是在函数体中执行的,每个函数主体都会被放在栈内存中,比如main函数。假如main函数里调用了其他的函数,比如add(),那么在栈里面的的存储就是最底层是main,mian上面是add。栈的运行时后入先出的,所以会执行时会先销毁add,再销毁main。

栈的优势是,栈内存与堆内存相比是非常小的,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄。栈有一个很重要的特殊性,就是存在栈中的数据可以共享。

二、堆内存

存放所有new出来的对象和数组
     特此强调,堆内存和数据结构中的堆完全是两码事,分配方式倒是类似于链表
      堆内存是区别于栈区、全局数据区和代码区的另一个内存区域。堆允许程序在运行时动态地申请某个大小的内存空间,堆内存实际上指的就是(满足堆内存性质的)优先队列的一种数据结构,第1个元素有最高的优先权。

在堆内存分配时首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放本内存空间。

另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。堆内存是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆内存的大小受限于计算机系统中有效的虚拟内存。由此可见,堆内存获得的空间比较灵活,也比较大。堆内存是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。

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

三、其他数据存储
    1、常量池:存放基本类型常量和字符串常量(public static final)
    2、静态域:存放静态成员(static定义的)
    3、非RAM存储:硬盘等永久存储空间

堆内存和栈内存的区别:
   1、应用程序所有的部分都使用堆内存,然后栈内存通过一个线程运行来使用。
   2、不论对象什么时候创建,他都会存储在堆内存中,栈内存包含它的引用。栈内存只包含原始值变量好和堆中对象变量的引用。
   3、存储在堆中的对象是全局可以被访问的,然而栈内存不能被其他线程所访问。
   4、栈中的内存管理使用LIFO的方式完成,而堆内存的管理要更复杂了,因为它是全局被访问的。
   5、栈内存是生命周期很短的,然而堆内存的生命周期从程序的运行开始到运行结束。
   6、我们可以使用-Xms和-Xmx JVM选项定义开始的大小和堆内存的最大值,我们可以使用-Xss定义栈的大小
   7、当栈内存满的时候,Java抛出java.lang.StackOverFlowError异常而堆内存满的时候抛出java.lang.OutOfMemoryError: Java Heap Space错误
   8、和堆内存比,栈内存要小的多,因为明确使用了内存分配规则(LIFO),和堆内存相比栈内存非常快。

总结:
   1 栈:为编译器自动分配和释放,如函数参数、局部变量、临时变量等等
   2 堆:为成员分配和释放,由程序员自己申请、自己释放。否则发生内存泄露。典型为使用new申请的堆内容。
        除了这两部分,还有一部分是:
   3 静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。

浅析JAVA中堆内存与栈内存的区别的更多相关文章

  1. Java中堆(heap)和栈(stack)的区别

    简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分 ...

  2. 转载C#中堆(heap)和栈(stack)的区别

    转载原地址  http://www.cnblogs.com/wangshenhe/archive/2013/02/18/2916275.html [转]C#堆和栈的区别 理解堆与栈对于理解.NET中的 ...

  3. Java中堆内存和栈内存详解2

    Java中堆内存和栈内存详解   Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...

  4. Java SE之Java中堆内存和栈内存[转/摘]

    [转/摘]1-3Java中堆内存和栈内存 注解:内存(Memory)即 内存储器,主存,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器(辅存)交换的数据. Java中把内存分为两种:栈 ...

  5. 浅析JS中的堆内存与栈内存

    最近跟着组里的大佬面试碰到这么一个问题, Q:说说var.let.const的区别 A:balabalabalabla... Q:const定义的值能改么? A:你逗我?不能吧 不知道各位看官怎么想? ...

  6. 熟悉java堆内存和栈内存和mysql的insert语句中含有id的处理

    java的堆内存和栈内存有什么区别呢? 如果mysql数据库表的id是递增的,如果没有插入id,则id自增,如果插入id,则插入什么就显示什么.

  7. JAVA内存管理之堆内存和栈内存

    我们常常做的是将Java内存区域简单的划分为两种:堆内存和栈内存.这种划分比较粗粒度,这种划分是着眼于我们最关注的.与对象内存分配密切相关的两类内存域.其中栈内存指的是虚拟机栈,堆内存指的是java堆 ...

  8. java堆内存和栈内存的处理

    前段时间学习二叉树在处理删除操作的时候遇到一个头疼的问题:删除节点的时候明明已经置null了可树上该节点依旧存在,还必须执行node.father.left = null;才可以删除node节点,寻找 ...

  9. java堆内存与栈内存

    java的内存分为两种,堆内存与栈内存: 堆内存用来存放数组和new的对象,比如一个文件,字节流是存放在堆中,栈内存为这个文件开辟一个索引,也就是这个文件的地址,并且保存在栈中.对象由GC处理释放内存 ...

随机推荐

  1. SpringCloud断路器监控面板——Hystrix Dashboard

    一.简介 Hystrix Dashboard是Hystrix的一个组件,Hystrix Dashboard提供一个断路器的监控面板,可以使我们更好的监控服务和集群的状态,仅仅使用Hystrix Das ...

  2. Java并发编程笔记之ReentrantLock源码分析

    ReentrantLock是可重入的独占锁,同时只能有一个线程可以获取该锁,其他获取该锁的线程会被阻塞后放入该锁的AQS阻塞队列里面. 首先我们先看一下ReentrantLock的类图结构,如下图所示 ...

  3. XSS漏洞扫描工具:BruteXSS

    下载Brute,一个xss漏洞扫描工具:https://codeload.github.com/shawarkhanethicalhacker/BruteXSS/legacy.zip/master 我 ...

  4. python的Web框架,类视图

    类视图 范式 from django.views import View # 继承View class IndexView(View): def get(self, request): #写法和函数视 ...

  5. [LeetCode解题报告] 703. 数据流中的第K大元素

    题目描述 设计一个找到数据流中第K大元素的类(class).注意是排序后的第K大元素,不是第K个不同的元素. 你的 KthLargest 类需要一个同时接收整数 k 和整数数组nums 的构造器,它包 ...

  6. 分部类,分部方法 - 修饰符partial

    一.分部类 什么是部分类呢?简单来说就是将一个类型或方法拆分到两个或多个源文件中,每个源文件只包含类型定义的一部分. 当使用自动生成的源时,无须重新创建源文件便可将代码添加到类中.Visual Stu ...

  7. 无法打开锁文件 /var/lib/dpkg/lock - open (13: 权限不够)

    比如输入apt-get install eclipse,或者apt-get update 会提示 无法打开锁文件 /var/lib/dpkg/lock - open (13: 权限不够)  无法对状态 ...

  8. yapi部署文档

    windows 下 yapi部署文档 安装nodejs 安装mongodb 安装yapi 介绍 随着 web 技术的发展,前后端分离成为越来越多互联网公司构建应用的方式.前后端分离的优势是一套 Api ...

  9. 【HttpWeb】Post和GET请求基本封装

    别的不多少了直接代码就行了: using System; using System.Collections.Generic; using System.Linq; using System.Text; ...

  10. Java基础——Oracle(六)

    一.数据字典和动态性能视图 数据字典: oracle中的重要组成部分,提供了数据库的一些系统信息,记录了数据库的系统信息,它是只读表和视图的集合,数据字典的所有者为 sys 用户.用户只能在数据字典上 ...