【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 ...
随机推荐
- notepad2正则表达式替换字符串
例子: 1-385-463-3226替换成13854633226 Ctrl+H开启替换,选中'regular expression search'或者正则表达式: 上面输入:1-(.*)-(.*)-( ...
- P1104 最大公约数和最小公倍数问题
题目描述 输入2个正整数 \(x0, y0 (2 \le x0 \lt 100000, 2 \le y0 \le 1000000)\) ,求出满足下列条件的 P,Q 的个数. 条件: P,Q是正整数 ...
- 为什么阿里代码规约要求避免使用 Apache BeanUtils 进行属性复制
缘起 有一次开发过程中,刚好看到小伙伴在调用 set 方法,将数据库中查询出来的 Po 对象的属性拷贝到 Vo 对象中,类似这样: 可以看出,Po 和 Vo 两个类的字段绝大部分是一样的,我们一个个地 ...
- post提交方式为什么要序列化,而Get提交方式就不用?序列化做了什么?
这是因为后台能够直接处理的数据格式,是一种经过序列化的键值对数据,比如前端要向后台提交三个参数,分别是a=1,b=2,c=3,那么后台接收到的数据就应该是a=1&b=2&c=3(可以看 ...
- 使用Python内置的smtplib包和email包来实现邮件的构造和发送。
此文章github地址:https://github.com/GhostCNZ/Python_sendEmail Python_sendEmail 使用Python内置的smtplib包和email包 ...
- 深入理解Jvm--Java静态分配和动态分配完全解析
jvm中分配Dispatch的概念 分派是针对方法而言的,指的是方法确定的过程,通常发生在方法调用的过程中.分派根据方法选择的发生时机可以分为静态分派和动态分派,其中对于动态分派,根据宗量种数又可以分 ...
- H3C 端口隔离简介
- Python3使用过程中需要注意的点
命名规则 变量 变量名只能是数字.字母或下划线的任意组合 变量名的第一个字符不能是数字 不能使用关键字作为变量名 变量的定义要具有可描述性 变量名不宜过长.不宜使用中文.拼音 常量(常用在配置文件中) ...
- 【39.87%】【BZOJ 1880】[Sdoi2009]Elaxia的路线
Time Limit: 4 Sec Memory Limit: 64 MB Submit: 1041 Solved: 415 [Submit][Status][Discuss] Descripti ...
- jquery中报错Uncaught ReferenceError: $ is not defined的解决办法
jquery中报错提示为:Uncaught ReferenceError: $ is not defined 这个错误的原因就是你没有引入jquery库文件或者引入的路径不对造成的