Java中堆内存(heap)和栈内存(stack)的区别
在Java代码中,常常会使用到这样的类的声明实例化:
Person per = new Person();
//这其实是包含了两个步骤,声明和实例化
Person per = null; //声明一个名为Person类的对象per
per = new Person(); // 实例化这个per对象
声明 指的是创建类的对象的过程;
实例化 指的是用关键词new来开辟内存空间。
它们在内存中的划分是这样的:

那什么是栈内存(heap)和栈内存(heap)呢?
栈内存:
在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。栈内存主要存放的是基本类型类型的数据 如( int, short, long, byte, float, double, boolean, char) 和对象句柄。注意:并没有String基本类型、在栈内存的数据的大小及生存周期是必须确定的、其优点是寄存速度快、栈数据可以共享、缺点是数据固定、不够灵活。
栈的共享:
String str1 = "myString";
String str2 = "myString";
System.out.println(str1 ==str2 );
//注意:这里使用的是str1 ==str2,而不是str1.equals(str2)的方式。
//因为根据JDK的说明,==号只有在两个引用都指向了同一个对象时才返回真值
//而str1.equals(str2),只是比较两个字符串是否相等
结果为True,这就说明了str1和str2其实指向的是同一个值。
上述代码的原理是,首先在栈中创建一个变量为str1的引用,然后查找栈中是否有myString这个值,如果没找到,就将myString存放进来,然后将str1指向myString。接着处理String str2 = "myString";;在创建完str2 的引用变量后,因为在栈中已经有myString这个值,便将str2 直接指向myString。这样,就出现了str1与str2 同时指向myString。
特别注意的是,这种字面值的引用与类对象的引用不同。假定两个类对象的引用同时指向一个对象,如果一个对象引用变量修改了这个对象的内部状态,那么另一个对象引用变量也即刻反映出这个变化。相反,通过字面值的引用来修改其值,不会导致另一个指向此字面值的引用的值也跟着改变的情况。如上例,我们定义完str1与str2 的值后,再令str1=yourString;那么,str2不会等于yourString,还是等于myString。在编译器内部,遇到str1=yourString;时,它就会重新搜索栈中是否有yourString的字面值,如果没有,重新开辟地址存放yourString的值;如果已经有了,则直接将str1指向这个地址。因此str1值的改变不会影响到str2的值。
堆内存:
堆内存用来存放所有new 创建的对象和 数组的数据
String str1 = new String ("myString");
String str2 = "myString";
System.out.println(str1 ==str2 ); //False
String str1 = new String ("myString");
String str2 = new String ("myString");
System.out.println(a==b); //False
创建了两个引用,创建了两个对象。两个引用分别指向不同的两个对象。以上两段代码说明,只要是用new()来新建对象的,都会在堆中创建,而且其字符串是单独存值的,即使与栈中的数据相同,也不会与栈中的数据共享。
Java中堆内存(heap)和栈内存(stack)的区别的更多相关文章
- JAVA虚拟机中的堆内存Heap与栈内存Stack
原文链接:http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/gc-Stack.html 深入Java虚拟机:JVM中的Stack和Heap 在JV ...
- JVM内存—堆(heap)栈(stack)方法区(method) (转)
JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 堆区:1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令 ...
- 浅析JAVA中堆内存与栈内存的区别
Java把内存划分成两种:一种是栈内存,一种是堆内存. 一.栈内存 存放基本类型的变量,对象的引用和方法调用,遵循先入后出的原则. 栈内存在函数中定义的“一些基本类型的变量和对象的引用变量”都 ...
- Java中堆内存和栈内存详解2
Java中堆内存和栈内存详解 Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...
- Java中堆(heap)和栈(stack)的区别
简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分 ...
- (转)java内存分配分析/栈内存、堆内存
转自(http://blog.csdn.net/qh_java/article/details/9084091) java内存分配分析/栈内存.堆内存 java内存分配分析 本文将由浅入深详细介绍Ja ...
- Java中的成员初始化顺序和内存分配过程
Java中的成员初始化顺序和内存分配过程 原帖是这样描述的: http://java.dzone.com/articles/java-object-initialization?utm_source= ...
- Java中堆与栈
简单的说:Java把内存划分成两种:一种是栈内存,一种是堆内存. 1:什么是堆内存: 堆内存是是Java内存中的一种,它的作用是用于存储Java中的对象和数组,当我们new一个对象或者创建一个数组的时 ...
- 让你彻底明白JAVA中堆与栈的区别
原文地址:http://www.2cto.com/kf/201302/190704.html 简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象 ...
- Java中堆和栈的区别(转)
栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new. ...
随机推荐
- java项目使用Echarts 做柱状堆叠图,包含点击事件
基础知识请自行百度查看,以下直接贴出实现代码: <%@ page pageEncoding="UTF-8"%><!DOCTYPE html><html ...
- angularJS服务一
一 认识服务 1.服务这个概念其实并不陌生,在其他语言中如java便有这样的概念,其作用就是对外提供某个特定的功能,如消息服务,文件压缩服务等,是一个独立的模块.ng的服务是一个单例对象或函数,对外提 ...
- Solr和ES对比
Solr与ES(ElasticSearch)对比 搜索引擎选择: Elasticsearch与Solr 搜索引擎选型调研文档 Elasticsearch简介* Elasticsearch是一个实时的分 ...
- WebService-通俗讲解
一.序言 大家或多或少都听过 WebService(Web服务),有一段时间很多计算机期刊.书籍和网站都大肆的提及和宣传WebService技术,其中不乏很多吹嘘和做广告的成 分.但是不得不承认的是W ...
- PHP安全编程:网站安全设计的一些原则(转)
深度防范 深度防范原则是安全专业人员人人皆知的原则,它说明了冗余安全措施的价值,这是被历史所证明的. 深度防范原则可以延伸到其它领域,不仅仅是局限于编程领域.使用过备份伞的跳伞队员可以证明有冗余安全措 ...
- MFC和Qt优缺点
在网上看到的,拿来和大家一起讨论下. 我曾经使用过来开发过软件,我想和大家分享我使用他们时所体会的不同之处. 我并非一个职业作家,这篇文章可能看起来不如专业的杂志和网站上的那么条理清晰.但是,我在这里 ...
- rabbitmq Clustering Guide--官方
官方文档地址:http://www.rabbitmq.com/documentation.html A RabbitMQ broker is a logical grouping of one or ...
- 关于Build Active Architecture Only属性
关于Build Active Architecture Only属性 Architecture 属性在BuildSetting里. 这个属性设置为yes,是为了debug的时候编译速度更快,它只编译当 ...
- android中的Handler和Runnable
最近在做一个项目,在网络请求时考虑用Handler进行处理,然后就研究了一下Handler和Runnable 首先在看一下java中的Runnable The Runnable interface s ...
- 1_Linux_目录简介
1. Linux中所以内容以文件形式保存,包括硬件,所以在用命令行配置文件时,该配置仅仅是临时生效. 2. Linux不靠扩展名区分类型,而是靠文件权限.之所以有扩展名是为了便于管理. .rpm二 ...