在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)的区别的更多相关文章

  1. JAVA虚拟机中的堆内存Heap与栈内存Stack

    原文链接:http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/gc-Stack.html 深入Java虚拟机:JVM中的Stack和Heap 在JV ...

  2. JVM内存—堆(heap)栈(stack)方法区(method) (转)

    JAVA的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method) 堆区:1.存储的全部是对象,每个对象都包含一个与之对应的class的信息.(class的目的是得到操作指令 ...

  3. 浅析JAVA中堆内存与栈内存的区别

    Java把内存划分成两种:一种是栈内存,一种是堆内存. 一.栈内存 存放基本类型的变量,对象的引用和方法调用,遵循先入后出的原则.     栈内存在函数中定义的“一些基本类型的变量和对象的引用变量”都 ...

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

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

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

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

  6. (转)java内存分配分析/栈内存、堆内存

    转自(http://blog.csdn.net/qh_java/article/details/9084091) java内存分配分析/栈内存.堆内存 java内存分配分析 本文将由浅入深详细介绍Ja ...

  7. Java中的成员初始化顺序和内存分配过程

    Java中的成员初始化顺序和内存分配过程 原帖是这样描述的: http://java.dzone.com/articles/java-object-initialization?utm_source= ...

  8. Java中堆与栈

    简单的说:Java把内存划分成两种:一种是栈内存,一种是堆内存. 1:什么是堆内存: 堆内存是是Java内存中的一种,它的作用是用于存储Java中的对象和数组,当我们new一个对象或者创建一个数组的时 ...

  9. 让你彻底明白JAVA中堆与栈的区别

    原文地址:http://www.2cto.com/kf/201302/190704.html 简单的说: Java把内存划分成两种:一种是栈内存,一种是堆内存. 在函数中定义的一些基本类型的变量和对象 ...

  10. Java中堆和栈的区别(转)

    栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆.      Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new. ...

随机推荐

  1. 348. Design Tic-Tac-Toe

    提示给的太直白了.. 比如player 1占据了(0,1),那么row[0]++ col[1]++ 表示第一行有1个O,第一列有1个X,假设PLAYER 1最终在第一行连成一排,那最终row[0] = ...

  2. cgdb调试postgresql

    之前一直用gdb调试代码,最近在搞pg的时候用了一个cgdb,体验很好,调试pg代码的时候真的很方便. 本文主要讲解在进行pg内核开发的时候,如何搭建一个环境,用cgdb方便快捷的调试postgres ...

  3. boost------bind的使用(Boost程序库完全开发指南)读书笔记

    bind是c++98标准库中函数适配器bind1st/bind2nd的泛化和增强,可以适配任意的可调用类型,包括函数指针.函数引用.成员函数指针和函数对象. 1.工作原理 bind并不是一个单独的类或 ...

  4. HDU-3473Minimum Sum

    Problem Description You are given N positive integers, denoted as x0, x1 ... xN-1. Then give you som ...

  5. cocos2dx c++ 在mac下写的中文凝视,在win32下编译时不通过

    今天遇到个奇怪的问题,在mac下写的程序,加的中文凝视,编译没有问题,可是在win32下(使用的时vs2012, win7 64bit 系统)编译就总是报错 最后在中文凝视后 加一个空格,或者 换行, ...

  6. Java 理论与实践: 用弱引用堵住内存泄漏---转载

    要让垃圾收集(GC)回收程序不再使用的对象,对象的逻辑 生命周期(应用程序使用它的时间)和对该对象拥有的引用的实际 生命周期必须是相同的.在大多数时候,好的软件工程技术保证这是自动实现的,不用我们对对 ...

  7. linux的文本管道连接处理技巧

    举例1: strace -f -e open cpp Hello.cpp -o /dev/null 2>&1 | grep -v ENOENT | awk '{print $3}' 1) ...

  8. git 创建远程仓库

    在远程服务器上$ cd /server/path/ $ git init --bare myproject.git 在本地 1> $ cd /client/path/ 运行 git init 2 ...

  9. javascript 实用函数

    1.去除字符串空格 /*去左空格*/ function ltrim(s) { return s.replace(/^(\s*| *)/, ""); } /*去右空格*/ funct ...

  10. maven update 以后报错。

    java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start com ...