java 内存深度解析
java 中的包括以下几大种的内存区域:1.寄存器 2.stack(栈) 3.heap(堆) 4.数据段 5.常量池
那么相应的内存区域中又存放什么东西(主要介绍 stack heap)?
栈:1.基本数据类型的值(4类8种); 2.类的实例(堆区对象的引用) 3.局部变量和形参 4.return xx;会在stack中存在一个临时内存
堆:1.new出来的对象 2.类的对象拥有的成员变量,但是他们存储在各自的堆中。类的成员变量在不通对象中各不相同,都有自己的存储空间。
栈(stack)与堆(heap)优劣势:
1. stack内存存储容量较小,但是存取速度比heap快很多!
存储在栈中的数据大小跟生命周期必须确定,失去机动性。但是stack中的数据具有共享性!
理解stack的共享性:
int a=3; a是基本类型变量,存储在stack中,占有一块空间,空间名称是a,里面的值是3;
此时定义 int b=3;b也存储在stack中,但是不会占用stack的内存空间,因为编译器会先查找在stack中是否存在值为3的空间地址,若存在,则3还有另一个空间名称即 b。
读到这里可能会有一个问题: 假如我把a进行重新赋值,a=4,这时候b=4? 理所当然不不会!!!
因为当对a=4时,编译器会在stack重新查找有没有存在值为4的空间地址,如果没有则会在stack重新开辟地址为4的空间。b此时还是保持不变,占用没有a所开辟的空间地址!
2. heap内存存储容量较大, 堆可以动态的分配内存,跟C++中差不多,但是C++中的内存是手动释放,而jVM中存在垃圾收集器会自动收走这些不在引用的数据。由于要运行new,所以存取速度低于stack!
下面代码:
1 package com.Demo; 2 3 class BirthDate { 4 private int day; 5 private int month; 6 private int year; 7 8 public void setDay(int day) { 9 this.day = day; 10 } 11 12 public void disPlay() { 13 System.out.println("Year "+ year +"month "+month+"Day "+day); 14 } 15 16 public BirthDate(int _day,int _month,int _year) { 17 day=_day; 18 month=_month; 19 year=_year; 20 } 21 } 22 23 24 public class test { 25 26 public void change1(int i) { 27 i=1234; 28 } 29 30 public void change2(BirthDate b) { 31 b=new BirthDate(22,2,2004); 32 } 33 34 public void change3(BirthDate b) { 35 b.setDay(22); 36 } 37 38 /* 39 * 详细分析内存 程序执行的过程 40 */ 41 public static void main(String[] args){ 42 test t=new test(); 43 int date=9; 44 BirthDate b1=new BirthDate(30,12,1995); 45 BirthDate b2=new BirthDate(23,8,1996); 46 t.change1(date); 47 t.change2(b1); 48 t.change3(b2); 49 } 50 51 }
程序在内存中的运行过程:
马老师说过:弄清楚了内存就弄清了一切!