`
582938697
  • 浏览: 83482 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

java堆、栈和常量池

    博客分类:
  • java
阅读更多

 

今天复习了一下这些知识,顺便做了下笔记.
1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.
2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。)
3. 堆:存放所有new出来的对象。
4. 静态域:存放静态成员(static定义的)
5. 常量池:存放字符串常量和基本类型常量(public static final)。
6. 非RAM存储:硬盘等永久存储空间

这里我们主要关心栈,堆和常量池,对于栈和常量池中的对象可以共享,对于堆中的对象不可以共享。栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会消失。堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。
对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。
如以下代码:

Java代码 
  1. String s1 = "china";  
  2. String s2 = "china";  
  3. String s3 = "china";  
  4. String ss1 = new String("china");  
  5. String ss2 = new String("china");  
  6. String ss3 = new String("china");  


这里解释一下黄色这3个箭头,对于通过new产生一个字符串(假设为”china”)时,会先去常量池中查找是否已经有了”china”对象,如果没有则在常量池中创建一个此字符串对象,然后堆中再创建一个常量池中此”china”对象的拷贝对象。这也就是有道面试题:String s = new String(“xyz”);产生几个对象?一个或两个,如果常量池中原来没有”xyz”,就是两个。



对于基础类型的变量和常量:变量和引用存储在栈中,常量存储在常量池中。
如以下代码:

Java代码 
  1. int i1 = 9;  
  2. int i2 = 9;  
  3. int i3 = 9;   
  4. public static final int INT1 = 9;  
  5. public static final int INT2 = 9;  
  6. public static final int INT3 = 9;  




对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量;局部变量就是方法或语句块内部定义的变量。局部变量必须初始化。
形式参数是局部变量,局部变量的数据存在于栈内存中。栈内存中的局部变量随着方法的消失而消失。
成员变量存储在堆中的对象里面,由垃圾回收器负责回收。
如以下代码:

Java代码 
  1. class BirthDate {  
  2.     private int day;  
  3.     private int month;  
  4.     private int year;      
  5.     public BirthDate(int d, int m, int y) {  
  6.         day = d;   
  7.         month = m;   
  8.         year = y;  
  9.     }  
  10.     省略get,set方法………  
  11. }  
  12.   
  13. public class Test{  
  14.     public static void main(String args[]){  
  15. int date = 9;  
  16.         Test test = new Test();        
  17.            test.change(date);   
  18.         BirthDate d1= new BirthDate(7,7,1970);         
  19.     }    
  20.   
  21.     public void change1(int i){  
  22.         i = 1234;  
  23.     }  



}


对于以上这段代码,date为局部变量,i,d,m,y都是形参为局部变量,day,month,year为成员变量。下面分析一下代码执行时候的变化:
1. main方法开始执行:int date = 9;
date局部变量,基础类型,引用和值都存在栈中。
2. Test test = new Test();
test为对象引用,存在栈中,对象(new Test())存在堆中。
3. test.change(date);
i为局部变量,引用和值存在栈中。当方法change执行完成后,i就会从栈中消失。
4. BirthDate d1= new BirthDate(7,7,1970);  
d1为对象引用,存在栈中,对象(new BirthDate())存在堆中,其中d,m,y为局部变量存储在栈中,且它们的类型为基础类型,因此它们的数据也存储在栈中。day,month,year为成员变量,它们存储在堆中(new BirthDate()里面)。当BirthDate构造方法执行完之后,d,m,y将从栈中消失。
5.main方法执行完之后,date变量,test,d1引用将从栈中消失,new Test(),new BirthDate()将等待垃圾回收。

 

文章转载自:http://www.iteye.com/topic/634530

 

分享到:
评论

相关推荐

    Java堆、栈和常量池——内存剖析

    ### Java堆、栈和常量池——内存剖析 #### 寄存器 寄存器作为最快的存储区域之一,由编译器自动管理分配与回收,它位于CPU内,用于存储临时变量,例如局部变量和一些操作数。由于寄存器的数量有限且由编译器自动...

    Java堆,栈和常量池详解

    ### Java堆、栈和常量池详解 #### Java内存模型概览 在深入探讨Java中的堆、栈以及常量池之前,我们先来简要回顾一下Java内存模型的基本概念。Java程序运行时会使用到不同的内存区域来存储各种类型的数据,这些...

    java 内存中 堆、栈、常量池、方法区的总结

    在常量池和栈中,数据是可以共享的。例如,当两个相同的字符串常量在常量池中时,它们实际上是指向同一个内存地址的引用。在栈中,基本类型的数据也是可以共享的,如两个整数变量可以引用相同的数值。而在堆中,对象...

    java内存分配之常量池,栈,堆1

    在Java中,内存主要分为四个区域:寄存器、栈、堆和方法区(包括常量池)。以下是这四个区域的详细说明: 1. **寄存器**: 这是计算机硬件的一部分,用于存储非常快速访问的数据。在Java中,寄存器主要由JVM直接管理...

    Java堆、栈和常量池详解

    易混点完美解析

    Java中的堆、栈和常量池_.docx

    在Java中,内存被划分为几个不同的区域,包括堆、栈、常量池和寄存器等。下面我们将详细讨论这些概念。 1. 寄存器: 寄存器是计算机硬件的一部分,用于快速访问数据。在Java中,寄存器由编译器根据需要自动分配和...

    Java堆、栈和常量池

    Java编程语言中的内存管理是通过堆、栈和常量池三个关键区域来实现的,这些区域各有其特定的用途和特点。 首先,寄存器是最快的存储区,它由编译器自动分配和管理,程序员无法直接控制。寄存器主要用于存储运算过程...

    java堆-栈-堆栈常量池的区别,史上最全总结

    总结来说,Java的堆和栈分别服务于不同类型的变量和对象,而常量池则提供了一种优化内存使用的方法。理解这些概念对于编写高效且内存友好的Java代码至关重要。在实际编程中,合理地利用栈、堆和常量池可以帮助我们更...

    详解java堆和栈

    ### 详解Java堆和栈 #### 一、引言 在Java编程中,理解堆(Heap)和栈(Stack)的概念及其区别对于程序员来说至关重要。本文将深入剖析这两个概念,并探讨它们之间的差异以及如何影响程序的运行。 #### 二、Java...

    Java 中的堆和栈

    在Java中,内存主要分为两个区域:栈内存和堆内存。这两部分内存各自有不同的特点和用途。 首先,栈内存主要负责存储基础数据类型(如byte, short, int, long, float, double, boolean, char)和对象的引用。当在...

    Java String 字符串常量池解析

    了解字符串常量池的位置是非常重要的,字符串常量池存在于方法区中,而堆和栈是不同的存储区域。堆存储的是对象,每个对象都包含一个与之对应的 Class,JVM 只有一个堆区,被所有线程共享。栈每个线程包含一个栈区,...

    关于Java栈与堆的思考

    2. 在字符串常量池中查找是否存在值为"abc"的字符串,若不存在则创建一个新的`String`对象,并将字符串值"abc"放入常量池,若存在则直接返回该字符串的引用。 3. 将变量`str`指向这个`String`对象的引用。 这种方式...

    string常量池和intern_韩雅茹Java系列2021.pdf

    字符串常量池和intern 字符串常量池是Java语言中的一种机制,旨在节省空间和提高性能。它是一个内存区域,所有的Java类共享这个池子。字符串常量池的设计思想是为了解决字符串的频繁创建问题,减少内存开销和提高...

    Java数据结构之栈与堆

    Java 数据结构中的栈和堆是两种重要的内存管理方式,它们在程序执行时分别扮演着不同的角色。栈主要负责存储程序运行过程中的局部变量、函数调用等信息,而堆则是用于动态分配对象内存的区域。 栈的优势在于其存取...

    深入堆与栈 堆与栈的区别

    通过对上述示例的分析,我们可以看出,理解堆和栈的概念对于Java程序员来说非常重要。栈主要用于存储基本类型的变量和对象的引用,而堆则用于存储所有对象实例的实际数据。此外,字符串常量池的概念也非常重要,它...

    java里的堆和栈

    ### Java里的堆和栈 #### 一、概述 在Java编程中,“堆”与“栈”的概念至关重要。它们是程序运行时内存管理的核心部分。本文将深入探讨Java中堆和栈的区别及其工作原理。 #### 二、Java内存区域划分 在Java中,...

    java中的栈(深层了解java虚拟机对对象的内存分布)

    Java中的栈和堆分别承担着不同的角色:栈负责快速、高效的存储和管理基本类型和局部变量,而堆则提供了更加灵活的内存管理策略,适用于各种复杂对象和动态数据结构。理解这两种内存区域的工作机制,对于编写高效、...

    Java中堆和栈的区别

    - `a` 和 `b` 都指向了常量池中的 `"abc"` 字符串。由于它们都引用了同一个字符串对象,所以 `a == b` 返回 `true`。 - `c` 是通过 `new String("abc")` 创建的新对象,尽管它的内容与 `a` 和 `b` 相同,但是它位于...

Global site tag (gtag.js) - Google Analytics