【Java编程思想阅读笔记】Java数据存储位置
Java数据存储位置
P46页有感
一、前置知识
- 栈是由系统自动分配的,Java程序员对栈没有直接的操作权限,
- 堆是所有线程共享的内存区域,栈 是每个线程独享的。
- 堆是由程序员自己申请的,在使用new关键字创建一个对象的时候,对象就会被分配到堆内存中。并且由于栈是由系统自动分配的,因此申请的效率和速度是高于要使用new关键字申请内存的堆。
- 栈是一块连续的区域,并且栈的大小系统确定好的,当需要的栈空间小于剩余空间时,系统就会自动分配,否则会报栈溢出的错误;而堆空间则不是一块连续的区域,如果学过操作系统课程的可以知道,操作系统中有一个记录空闲内存地址的链表,当在申请堆内存时,系统会遍历这个链表,找到第一个内存空间符合申请空间的节点地址,然后将该节点从空闲链表中删除,再把内存空间分配给程序。详细的分配过程,可以去学习操作系统课程。
二、Java的六个存储位置
2.1.寄存器
寄存器位于CPU内部,这是计算机硬件中处理速度最快的地方,是真正的处理程序的位置。寄存器是由编译器根据需要来分配的,并且即便是编译器,也需要通过操作系统的抢占式调度才能够获得CPU的处理权,因此,寄存器的存储空间时非常有限的,开发人员对寄存器没有直接的控制权,在程序里也没法对寄存器有什么操作。
2.2.堆栈
堆栈一般也叫栈,一般指的是RAM区域,处理速度仅次于寄存器。在堆栈中,一般存放的都是对象的引用,当栈指针下移的时候,就创建新的内存,反之则释放内存。当创建一个对象时。该对象的会被放到堆内存的空间,而该对象的引用则会被放到栈内存中。并且Java 编译器必须准确地知道堆栈内保存的所有数据的“长度”以及“存
在时间”。以便回收空间和知道栈内存还剩余多少空间。
2.3.堆
堆内存也是在RAM区域,它是对象的真正存放位置,当new一个对象时,该对象就会被存放至堆内存,并且Java编译器不需要去在意堆中还剩多少空间,Java 有一个特别 的“垃圾收集器”,它会查找用new创建的所有对象,并辨别其中哪些不再被引用。随后,它会自动释放由 那些闲置对象占据的内存,以便能由新对象使用。这意味着我们根本不必操心内存的回收问题。只需简单地创建对象,一旦不再需要它们,它们就会自动离去。这样做可防止在C++里很常见的一个编程问题:由于程序员忘记释放内存造成的“内存溢出”,对象的销毁---对象的引用放在栈中,所以使用完引用就被从栈中销毁了,但是实际的对象仍然存放在堆中,只有在没有任何的引用使用它的时候才被垃圾回收器销毁掉。
class StaticTest {
Static int i = 47;
}
//现在我们 new两个对象
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();
//st1.i和st2.i都是47 尽管我们制作了两个StaticTest对象,但它们仍然只占据StaticTest.i的一个存储空间。这两个对象都共享同样的i 此时不管是哪个对象执行st1++,另一个对象的i也会加一
2.5.常量池
常数存储。常数值通常直接置于程序代码内部。这样做是安全的,因为它们永远都不会改变。有的常数 需要严格地保护,所以可考虑将它们置入ROM。
2.6 非RAM存储
非RAM存储。若数据完全独立于一个程序之外,则程序不运行时仍可存在,并在程序的控制范围之外。 其中两个最主要的例子便是“流式对象”和“固定对象”。对于流式对象,对象会变成字节流,通常会发给 另一台机器。而对于固定对象,对象保存在磁盘中。即使程序中止运行,它们仍可保持自己的状态不变。对 于这些类型的数据存储,一个特别有用的技巧就是它们能存在于其他媒体中。一旦需要,甚至能将它们恢复 成普通的、基于RAM的对象。Java 1.1提供了对Lightweight persistence的支持。未来的版本甚至可能提 供更完整的方案。
三、基本类型的存储位置
在Java编程思想中对于基本数据类型的存储位置有这么一句话
对于这些基本类型,Java 采纳了与C和C++相同的方法。也就是说,不是用 new创建变量,而是创建一个并非引用的“自动”变量。这个变量容纳了具体的值,并置于堆栈中,能够更 高效地存取。
但是我百度查找了一些相关资料,也有说基本数据类型有放在堆中的。梳理一下,首先,八大基本类型都不能看做对象,基本类型的存储位置要分情况,当基本类型的创建是在类中。像这样
class Demo{
int a = 1;//情况1
public int test(){
int b = 2;//情况2
}
}
在情况1下,创建的是全局变量。是随着对象一起存放在堆中的,在情况2下,创建的是局部变量,每当程序调用方法时,系统都会为该方法建立一个方法栈,其所在方法中声明的变量就放在方法栈中,当方法结束系统会释放方法栈,其对应在该方法中声明的变量随着栈的销毁而结束,这就局部变量只能在方法中有效的原因。由此可见,基本类型并不是完全存储在栈区的。原因是因为,上面基础知识提到的,堆是所有线程共享的内存区域,栈 是每个线程独享的。如果你将一个实例变量放在栈内,那么就不存在多个线程访问同一个对象资源了,这显然是不对的,所以全局变量要在堆上创建,也不是线程安全的。但是对于局部变量,是在栈上创建的,每一次方法调用创建一个方法栈,独享一份内存区域,其他的线程是不会访问到该线程的资源,在 栈上创建也会减轻GC的压力,随着该方法的结束,相对应的方法栈内存消除,这种局部变量占用的内存自然就消失了,因此局部变量是线程安全的。
【Java编程思想阅读笔记】Java数据存储位置的更多相关文章
- Java编程思想重点笔记(Java开发必看)
Java编程思想重点笔记(Java开发必看) Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...
- Java编程思想总结笔记Chapter 2
本章介绍Java程序的基本组成部分,体会到Java中几乎一切都是对象. 第二章 一切都是对象 目录: 2.1 用引用操纵对象 2.2 必须由你创建所有对象 2.3 永远不需要销毁对象 2.4 创建 ...
- Java编程思想总结笔记Chapter 5
初始化和清理是涉及安全的两个问题.本章简单的介绍“垃圾回收器”及初始化知识. 第五章 初始化与清理 目录:5.1 用构造器确保初始化5.2 方法重载5.3 默认构造器5.4 this关键字5.5 清 ...
- Java编程思想总结笔记Chapter 3
本章需要总结的不多,但细节的东西需要注意,有些很容易遗忘. 第三章 目录: 3.1 更简单的打印语句 3.2 使用Java操作符 3.3 优先级 3.4 赋值 3.5 算数操作符 3.6 自动递增和递 ...
- Java编程思想总结笔记The first chapter
总觉得书中太啰嗦,看完总结后方便日后回忆,本想偷懒网上找别人的总结,无奈找不到好的,只好自食其力,尽量总结得最好. 第一章 对象导论 看到对象导论觉得这本书 目录: 1.1 抽象过程1.2 每个对象 ...
- JAVA编程思想读书笔记(五)--多线程
接上篇JAVA编程思想读书笔记(四)--对象的克隆 No1: daemon Thread(守护线程) 参考http://blog.csdn.net/pony_maggie/article/detail ...
- JAVA编程思想读书笔记(三)--RTTI
接上篇JAVA编程思想读书笔记(二) 第十一章 运行期类型判定 No1: 对于作为程序一部分的每个类,它们都有一个Class对象.换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当的说, ...
- JAVA编程思想读书笔记(二)--容器
接上篇JAVA编程思想读书笔记(一) 第八章.对象的容纳 No1: java提供了四种类型的集合类:Vector(矢量).BitSet(位集).Stack(堆栈).Hashtable(散列表) No2 ...
- JAVA编程思想读书笔记(四)--对象的克隆
接上篇JAVA编程思想读书笔记(三)--RTTI No1: 类的克隆 public class MyObject implements Cloneable { int i; public MyObje ...
随机推荐
- Javassist指引(二)--ClassPool
原文链接 上一章: Javassist指引(一) 2.ClassPool ClassPool是一个CtClass的容器.因为编译器随时可能访问一个CtClass类,所以一旦一个CtClass创建,它将 ...
- SpringData Jpa、Hibernate、Jpa 三者之间的关系
JPA规范与ORM框架之间的关系是怎样的呢? JPA规范本质上就是一种ORM规范,注意不是ORM框架--因为JPA并未提供ORM实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服 ...
- Python 3里,reduce()函数已经被从全局名字空间里移除了,它现在被放置在fucntools模块里
reduce函数:在Python 3里,reduce()函数已经被从全局名字空间里移除了,它现在被放置在fucntools模块里 用的话要 先引入:>>> from functool ...
- MSBuild 常用参数
本文告诉大家在 MSBuild 里面常用的参数 一般的 msbuild 在编译的时候都会添加很多参数,用法如下 进入对应编译的 sln 或 csproj 文件所在的文件夹,执行下面命名 msbuild ...
- linux 内存区
GFP_DMA 和 GFP_HIGHMEM 都有一个平台相关的角色, 尽管对所有平台它们的使用都 有效. Linux 内核知道最少 3 个内存区: DMA-能够 内存, 普通内存, 和高端内存. 尽管 ...
- import()函数
简介 import命令会被 JavaScript 引擎静态分析,先于模块内的其他模块执行(叫做”连接“更合适).所以,下面的代码会报错. // 报错 if (x === 2) { import MyM ...
- Vue+node.js实现一个简洁的个人博客系统
本项目是一个用vue和node以及mysql实现的一个简单的个人博客系统,整体逻辑比较简单.但是可以我们完整的了解一个项目从数据库到后端到前端的实现过程,适合不太懂这一块的朋友们拿来练手. 本项目所用 ...
- 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)
2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...
- jedis 连接池工具类
maven <properties> <jedis.version>3.0.1</jedis.version> <junit.verion>4.12&l ...
- 闲着没事,做个chrome浏览器插件,适合初学者
时光偷走的,永远都是我们眼皮底下看不见的珍贵. 本插件功能:替换掉网页中的指定图片的src地址. 使用插件前: 使用插件后: 鲜花(闲话):这个网站的不加水印的图片连接被保存在,图片的data-ima ...