java内存中数据存储位置

java内存分配

  • 寄存器:程序无法控制,读写最快!
  • 栈:存放局部变量和对象的引用值,而对象本身则放在堆中(自动回收),可数据共享。
  • 堆:程序运行期被动态创建,存放在堆中。手动回收或者系统gc回收。
  • 静态域:存放对象中对象的static成员。
  • 常量池:存放常量。

存储位置

  • 先看一段程序吧:
int i=5;
int j=5;

那么这段程序中,内存发生了什么变化呢,首先会开辟一个i的存储区,然后会检查栈中有没有5这个值,如果没有,则保存到栈中,然后让i=5,接着开辟一个j的存储区,检查栈中是否有5,如果有,这直接让j=5。即所谓的栈内数据共享。

  • 再看一段程序
String s1 = "abc";
String s2 = new String(“abc”);
  1. String s = ”abc“的工作过程可以分为以下几个步骤:
    (1)定义了一个名为"s"的String类型的引用。
    (2)检查在常量池中是否存在值为"abc"的字符串对象;
    (3)如果不存在,则在常量池(字符串池)创建存储进一个值为"abc"的字符串对象。如果已经存在,则跳过这一步工作。
    (4)将对象引用s指向字符串池当中的”abc“对象。
  2. String s = new String(”abc“)的步骤则为:
    (1)定义了一个名为"s"的String类型的引用。
    (2)检查在常量池中是否存在值为"abc"的字符串对象;
    (3)如果不存在,则在常量池(字符串池)存储进一个值为"abc"的字符串对象。如果已经存在,则跳过这一步工作。
    (4)在堆中创建存储一个”abc“字符串对象。
    (5)将对象引用指向堆中的对象。
    这里指的注意的是,采用new的方式,虽然是在堆中存储对象,但是也会在存储之前检查常量池中是否已经含有此对象,如果没有,则会先在常量池创建对象,然后在堆中创建这个对象的”拷贝对象“。这也就是为什么有道面试题:String s = new String(“xyz”);产生几个对象?的答案是:一个或两个的原因。因为如果常量池中原来没有”xyz”,就是两个。
  • 最后,借助网上看到的一个例子帮助对栈内存,堆内存的存储进行理解:
class BirthDate {    
       private int day;    
       private int month;    
       private int year;        
       public BirthDate(int d, int m, int y) {    
           day = d;     
           month = m;     
           year = y;    
       }    
       省略get,set方法………    
   }    
       
   public class Test{    
       public static void main(String args[]){    
            int date = 9;    
            Test test = new Test();          
            test.change(date);     
            BirthDate d1= new BirthDate(7,7,1970);           
       }      
       
       public void change1(int i){    
           i = 1234;    
       }    
  • 对于以上这段代码,date为局部变量,i,d,m,y都是形参为局部变量,day,month,year为成员变量。下面分析一下代码执行时候的变化:
  • main方法开始执行:int date = 9; date局部变量,基础类型,引用和值都存在栈中。
  • Test test = new Test(); test为对象引用,存在栈中,对象(new Test())存在堆中。
  • test.change(date); 调用change(int i)方法,i为局部变量,引用和值- 存在栈中。当方法change执行完成后,i就会从栈中消失。
  • BirthDate d1= new BirthDate(7,7,1970);调用BIrthDate类的构造函数生成对象。d1为对象引用,存在栈中;
  • 对象(new BirthDate())存在堆中;其中d,m,y为局部变量存储在栈中,且它们的类型为基础类型,因此它们的数据也存储在栈中;day,month,year为BirthDate对象的的成员变量,它们存储在堆中存储的new BirthDate()对象里面;
  • 当BirthDate构造方法执行完之后,d,m,y将从栈中消失。
  • main方法执行完之后。date变量,test,d1引用将从栈中消失,new Test(),new BirthDate()将等待垃圾回收器进行回收。
    参考文章:https://blog.csdn.net/qq_36838191/article/details/80248182
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容