Java中对象的储存区
来源:互联网 发布:java log4j打印ibatis 编辑:程序博客网 时间:2024/06/18 16:50
两个重要的问题:
对象的数据位于何处?
如何控制对象的生命周期?
C语言中数据的存储区:
栈内存(Stack):主要是用来存储函数调用(function calls)和局部变量(local variables) 的内存区,它在内存中的数据结构本质就是一个栈(Stack)。需要注意的是,如果栈内存使用过多,就会出现所谓的堆栈溢位(Stack overflow),如死递归。
堆内存(Heap):主要是用来存储由 malloc() 申请的内存。如果 malloc() 返回NULL的话就表明内存用完。
静态内存(Static):它的生命周期与程序相同,即在进程创建是被创建,在程序退出时被销毁。全局作用域变量(global variables), 文件作用域变量(file scope variables)和被 static 修饰的变量会储存在这里。
寄存器(Register):这个关键字的作用是请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。需要注意的是:register这个关键字只是一个请求,请求CPU给你一个内存,给不给还在于CPU。
Java中对象的储存区:
栈:通过堆栈指针来操纵内存,指针下移则分配内存,指针上移则释放内存, 如图(图片来源于网络)
在程序创建的时候,必须知道储存在堆栈内所有的数据项,以便可以操纵指针,这样的约束就限制了Java的灵活性,所以部分数据存储在此,特别是对象的引用,而对象本身不储存并在其中。堆:用于存放所有的Java对象,不同于栈,它不需要知道数据在堆中的生存期,需要的时候便 new 一个对象出来,那么如何释放掉内存呢?不得不提的是Java中的垃圾回收机制了,不像C/C++需要手动释放内存,垃圾回收机制会自动地检测并释放无用的内存,避免了程序的内存泄漏问题。
常量储存:常量值一般直接存放在程序代码的内部,这样做是很安全的,因为是常量值,所以他们不希望被改变,也不会被改变。
寄存器:(编程人员不能控制,也感知不到,不做讨论)
- 非RAM储存:储存在磁盘上的对象。
Java为什么采用动态内存分配?
C/C++认为效率的控制是很重要的,那么在设计者在实现的时候给予了编程人员选择的权力,为了追求更快的速度和更高的效率,对象的存储空间和生命周期在编写程序的时候就确定,这种方式将存储空间的分配和释放放置于优先考虑的位置,但是某些情况这种方式也牺牲了灵活性,于是就有第二种方式。
第二种存储方式就是在堆内存中动态的创建,这种方式中,直到运行程序的时候才知道需要多少对象,才知道它们的生命周期及其属性,在需要的时候也可以在此时刻创建,即储存空间是动态管理的,但是这种方式需要花费大量的时间在堆中分配存储空间即释放内存空间,这可能要远远大于在堆栈中创建储存空间的时间,在堆栈中创建储存空间和释放储存空间各需要一条汇编指令即可。
所以Java设计者认为动态操作的方式虽然速度效率不及前者,但是在复杂的程序设计中,这种灵活方式反而提升了速度和效率,所以Java完全采用了动态内存分配方式(基本类型是特例)。
为什么基本类型是特例?
Java中的基本类型:
boolean、byte、char、short、int、long、float、double、(void)
boolean b = false;int i = 0;double d = 9.26;
如果基本类型往往是特别小而简单的变量,如果 new 一个对象出来,并不具有效率。
所以和C/C++一样,Java对待基本变量,把它储存在堆栈中,更具有效率。
为了让基本类型具有变量的特性,Java中也有相应的包裹类型,来应对不同的需求:
参考:
《Thinking in Java》 - Bruce Eckel
个人浅见,欢迎指正!
- Java中对象的储存区
- C语言中定义变量(储存区 栈)和用malloc(动态分配 堆)的区别
- java中对象和对象的引用
- java中对象和对象的引用
- Java中对象的上转型对象
- JAVA中对象和对象的引用
- Java中 对象的上转型对象
- java 中对象的引用
- Java中对象的克隆
- Java中对象的生命周期
- Java中对象的多态性
- java 中对象的描述
- Java中对象的销毁
- Java中对象的复制
- Java中对象的初始化
- Java中对象的引用
- Java 中对象的销毁
- java中对象的复制
- oracle两个数据库之间的内容对比
- Arraylist size()==0,null,isEmpty()的区别
- [oracle] exp-00091
- 用Java调用中国网建提供的SMS短信平台接口实现向移动端发送短信
- String 相关知识(后续会更新)
- Java中对象的储存区
- Tomcat的server.xml中的Context元素的一下参数应该怎么配置
- 形参、局部变量、局部静态变量的区别
- H5开发:fastclick取代tap
- 利用Flume将MySQL表数据准实时抽取到HDFS
- Java设计模式——享元模式(Flyweight Pattern)
- 调整虚拟机的尺寸
- ThreadLocal学习
- AB1601 烧写程序后上电后无反应