简要谈谈堆和栈的区别

今天读了《Think in JAVA》一书的1.10部分,对象的创建和生命周期,突然感觉这一部分是很常见又很容易被忽视的问题,故拿到此做一记录。

区别

栈区:由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。对象的存储空间和生命周期在编写程序时确定。这种方式将存储空间的分配和释放放在首位,但是牺牲了灵活性,必须在编写程序时知道对象的数量、生命周期和类型。

堆区:一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意与数据结构中的堆不一样。这种方式动态的创建销毁对象,知道运行时才能知道需要多少对象,生命周期如何以及具体类型时什么。

代码

//main.c
int a = 0; //全局初始化区   
char *p1;  //全局未初始化区   
void main()   
  {   
  int b;   //栈   
  char s[] = "abc";   //栈   
  char *p2;   //栈   
  char *p3 = "123456";   //"123456"在常量区,p3在栈上。   
  static int c =0//全局(静态)初始化区   
  p1 = (char*)malloc(10);   
  p2 = (char*)malloc(20); //p1,p2在栈里,分配的空间在堆中
  strcpy(p1,"123456");   //"123456"放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。   
  }    

注意c语言中的内存包括4块区域:栈、堆、全局区(静态区)、常量区。c++中包括5个区,和上述的类似,这里不再讲。

其他说明

  1. java完全采用动态内存的分配方式
  2. 在堆中创建对象时,C/C++必须通过编程方式来确定何时销毁对象,否则容易发生内存泄漏;而java提供了”垃圾回收器“机制,可以自动回收内存。
  3. Java中的数据类型有两种。
    一种是基本类型(primitive types)出于追求速度的原因,就存在于栈中。
    另一种是包装类数据,如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中,Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。
  4. String是一个特殊的包装类数据。即可以用String str = new String(“abc”);的形式来创建,也可以用String str = “abc”;的形式来创建。前者是规范的类的创建过程,即在Java中,一切都是对象,而对象是类的实例,全部通过new()的形式来创建。
    值得注意的是,一般String类中字符串值都是直接存值的。但像String str = “abc”;这种场合下,其字符串值却是保存了一个指向存在栈中数据的引用!
    用new()来新建对象的,都会在堆中创建,而且其字符串是单独存值的,即使与栈中的数据相同,也不会与栈中的数据共享
    使用String str = “abc”;的方式,可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String(“abc”);的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值