`
hejiajunsh
  • 浏览: 409881 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

jvm与堆和栈-栈的"数据共享"-实例化String对象的两种方法

阅读更多

《Java程序员 上班那点儿事》第4章为大家讲述的是控制内存的功力。本节为容易被搞晕的--堆和栈。

 

4.2 容易被搞晕的--堆和栈

由于"堆"和"栈"这两个概念是看不见摸不着的东西,让很多程序员都整不明白是怎么回事,其实这两个概念也没有什么好研究的,因为堆和栈程序员根本没有办法控制其具体内容。

我们只需要了解一点,栈与堆都是Java用来在内存中存放数据的地方就行了。然后再弄清楚这两个概念分别对应这程序开发的什么操作,以及堆和栈的区别即可。

4.2.1 堆--用new建立,垃圾自动回收负责回收

1、堆是一个"运行时"数据区,类实例化的对象就是从堆上去分配空间的;

2、在堆上分配空间是通过"new"等指令建立的;

3、Java针对堆的操作和C++的区别就是,Java不需要在空间不用的时候来显式的释放;

4、Java的堆是由Java的垃圾回收机制来负责处理的,堆是动态分配内存大小,垃圾收集器可以自动回收不再使用的内存空间。

5、但缺点是,因为在运行时动态分配内存,所以内存的存取速度较慢。

例如:

String str = new String("abc"); 

就是在堆上开辟的空间来存放String的对象。

4.2.2 栈--存放基本数据类型,速度快

1、栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char)和对象句柄;

2、栈的存取速度比堆要快;

3、栈数据可以共享;

4、栈的数据大小与生存期必须是确定的,缺乏灵活性。

例如:

int a = 3; 

就是在堆上开辟的空间来存放String的对象。

4.2.3 何谓栈的"数据共享"

栈其中一个特性就是"数据共享",那么什么是"数据共享"呢?

我们这里面所说的数据共享,并不是由程序员来控制的,而是JVM来控制的,指的是是系统自动处理的方式。

比如定义两个变量:

int a = 5;
int b = 5;

这两个变量所指向的栈上的空间地址是同一个,这就是所谓的"数据共享"。

它的工作方式是这样的:

JVM处理int a = 5,首先在栈上创建一个变量为a的引用,然后去查找栈上是否还有5这个值,如果没有找到,那么就将5存放进来,然后将a指向5。

接着处理int b = 5,在创建完b的引用后,因为在栈中已经有5这个值,便将b直接指向5。

于是,就出现了a与b同时指向5的内存地址的情况。

4.2.4 实例化对象的两种方法

对于String这个类来说它可以用两种方法进行建立:

String s = new String("asdf"); 

String s = "asdf"; 

用这两个形式创建的对象是不同的,第一种是用new()来创建对象的,它是在堆上开辟空间,每调用一次都会在堆上创建一个新的对象。

而第二种的创建方法则是先在栈上创建一个String类的对象引用,然后再去查找栈中有没有存放"asdf",如果没有,则将"asdf"存放进栈,并让str指向"asdf",如果已经有"asdf" 则直接把str指向"abc"。

我们在比较两个String是否相等时,一定是用"equals()"方法,而当测试两个包装类的引用是否指向同一个对象时,我们应该用"= ="。

因此,我们可以通过"= ="判断是否相等来验证栈上面的数据共享的问题。

例1:

String s1 = "asdf"; 
String s2 = "asdf";
System.out.println(s1==s2);

该程序的运行结果是,"true",那么这说明"s1"和"s2"都是指向同一个对象的。

例2:

String s1 =new String ("asdf"); 
String s2 =new String ("asdf");
System.out.println(s1==s2);

该程序的运行结果是,"false",这说明用new的方式是生成的对象,每个对象都指向不同的地方。

 

转自:http://book.51cto.com/art/200906/131809.htm

 

分享到:
评论

相关推荐

    堆和栈的区别

    Java编程语言中,内存管理是通过堆和栈两种机制实现的。栈主要处理基础类型变量和对象引用,而堆则是存储复杂对象和数组的主要区域。理解这两种内存区域的区别和工作原理对于优化代码性能至关重要。 首先,栈内存是...

    Java中堆内存和栈内存详解

    通过对Java中堆内存与栈内存的深入探讨,我们可以看到这两种内存区域各有其特点和用途。栈内存适用于存储临时数据,而堆内存则用于存储持久化数据。理解这些概念对于编写高效、稳定的Java程序至关重要。希望本文能够...

    java虚拟机JVM详解ppt

    本地方法栈与Java虚拟机栈类似,但主要支持Native方法的调用。在某些JVM实现中,它与Java虚拟机栈合并在一起。 ##### 4.5 方法区(Method Area) 方法区存储了每个类的信息(包括类的方法和字段)、常量池、静态变量...

    String类创建对象问题

    在 Java 中,`String` 类并不属于八种基本数据类型之一,而是作为一个对象存在。这意味着 `String` 对象默认值为 `null`。尽管如此,`String` 类拥有其独特之处,比如它是不可变的(final),这保证了字符串一旦创建便...

    jvm(21题).pdf

    2. 运行时数据区:包括PC寄存器、方法区、堆、栈和本地方法栈等,这些区域都会在线程创建时分配。 3. 执行引擎:包括垃圾回收器、即时编译器等,负责执行存储在方法区内的字节码。 下面我们将详细解析文件中提到的...

    学习jvm笔记.zip

    堆是所有线程共享的区域,用于存储对象实例。栈则为每个线程独有,存放方法调用时的局部变量、方法参数和返回地址。Java还提供了方法区和程序计数器,方法区存储类信息、常量、静态变量,程序计数器记录下一条要执行...

    JVM面试.docx

    - **功能**:也是线程共享的区域,主要用于存储对象实例和数组等。 - **特点**:同样存在多线程安全问题,需要通过同步机制来保证数据的一致性。 3. **虚拟机栈**: - **功能**:每个线程私有的,用于存储局部...

    最新java面试专题01-JVM

    - **堆内存**:所有线程共享的内存区域,主要用于存放对象实例。在Java中,几乎所有的对象实例都是在堆上分配内存的。 - **方法区**:也称为非堆区,用来存储已被加载的类信息、常量、静态变量以及编译后的代码等...

    JVM原理.docx

    - **堆**:所有线程共享,保存创建的对象实例。 - **PC寄存器**:每条线程私有,存储线程当前执行的下一条指令的位置。 - **Java堆栈**:每条线程私有,保存方法调用时的状态,如局部变量、参数等。 - **本地...

    JVM学习资源学习资源

    - **堆内存**(Heap):存储对象实例,是所有线程共享的一块区域,分为新生代(Young Generation)和老年代(Old Generation)。 - **新生代**:进一步细分为Eden区和两个Survivor区(From、To)。大部分对象在...

    Java面试题虚拟机片源码资料

    - 运行数据区(Runtime Data Area):包括方法区、堆、虚拟机栈、本地方法栈和程序计数器。 - 方法区:存储类的信息,如类名、常量池、字段和方法数据等。 - 堆:存放对象实例,所有线程共享,是垃圾收集的主要...

    JVM的相关概念.doc

    - **堆**:所有线程共享的内存区域,用于存放对象实例。 - **Java虚拟机栈**:描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。 - ...

    Java面试八股文十万字总结.docx

    - **JVM的内存模型**:包括堆、栈、方法区、程序计数器、本地方法栈等。 - **堆和栈的区别**:堆用于存储对象实例,栈用于存储局部变量和方法调用信息。 - **FullGC触发条件**:新生代满、老年代满、方法区满等情况...

    Java经典问题答案(带书签).pdf

    - 子类实例化过程中首先调用父类构造方法。 - 然后初始化子类成员变量,执行构造代码块,最后调用子类构造方法。 #### 四、异常 **Throw和Throws的区别** - `throw`用于在方法内部抛出异常。 - `throws`用于在...

    JVM面试题1

    3. **本地方法栈(Native Method Stack)**: - **作用**:与虚拟机栈类似,但是专门为Native方法服务。 - **特点**:线程独占,可能出现StackOverflowError和OutOfMemoryError。 4. **堆(Heap)**: - **作用**:...

    30道JVM综合面试题详解含答案(值得珍藏)

    JVM内存主要分为堆内存和栈内存两大部分,堆内存主要用来存放对象实例,而栈内存主要用于存储方法调用时的局部变量、操作数栈等。除此之外,还有方法区(存储类元数据)、程序计数器(记录下一条要执行的指令地址)...

    JVM 20道面试题和答案.docx

    }public static void main(String[] args) {}}在这个例子中,`Person` 类的两个实例 `p1` 和 `p2` 彼此引用,形成一个引用循环。尽管它们在 `gcTest()` 方法结束后就不再被引用,但由于它们之间存在循环引用,如果...

    java 栈和堆区别详细介绍

    在Java中,内存管理是自动化进行的,而内存分为两个主要部分:栈(Stack)和堆(Heap)。理解这两者的区别对于Java开发者来说至关重要,因为它影响着程序的性能和资源管理。下面将详细介绍Java栈和堆的区别。 首先...

    后端开发基础知识整理JAVA、JVM、操作系统、网络、设计模式、mysql、redis、多线程、spring、springboo

    - **堆栈的区别**:堆用于存储对象实例,栈用于存储局部变量和方法调用信息。 - **对象创建的五种方法**:new关键字、反射、克隆等。 - **new的过程**:内存分配、初始化、设置引用等步骤。 - **Java中的引用类型**...

Global site tag (gtag.js) - Google Analytics