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数据存储位置的更多相关文章

  1. Java编程思想重点笔记(Java开发必看)

    Java编程思想重点笔记(Java开发必看)   Java编程思想,Java学习必读经典,不管是初学者还是大牛都值得一读,这里总结书中的重点知识,这些知识不仅经常出现在各大知名公司的笔试面试过程中,而 ...

  2. Java编程思想总结笔记Chapter 2

    本章介绍Java程序的基本组成部分,体会到Java中几乎一切都是对象. 第二章   一切都是对象 目录: 2.1 用引用操纵对象 2.2 必须由你创建所有对象 2.3 永远不需要销毁对象 2.4 创建 ...

  3. Java编程思想总结笔记Chapter 5

    初始化和清理是涉及安全的两个问题.本章简单的介绍“垃圾回收器”及初始化知识. 第五章  初始化与清理 目录:5.1 用构造器确保初始化5.2 方法重载5.3 默认构造器5.4 this关键字5.5 清 ...

  4. Java编程思想总结笔记Chapter 3

    本章需要总结的不多,但细节的东西需要注意,有些很容易遗忘. 第三章 目录: 3.1 更简单的打印语句 3.2 使用Java操作符 3.3 优先级 3.4 赋值 3.5 算数操作符 3.6 自动递增和递 ...

  5. Java编程思想总结笔记The first chapter

    总觉得书中太啰嗦,看完总结后方便日后回忆,本想偷懒网上找别人的总结,无奈找不到好的,只好自食其力,尽量总结得最好. 第一章  对象导论 看到对象导论觉得这本书 目录: 1.1 抽象过程1.2 每个对象 ...

  6. JAVA编程思想读书笔记(五)--多线程

    接上篇JAVA编程思想读书笔记(四)--对象的克隆 No1: daemon Thread(守护线程) 参考http://blog.csdn.net/pony_maggie/article/detail ...

  7. JAVA编程思想读书笔记(三)--RTTI

    接上篇JAVA编程思想读书笔记(二) 第十一章 运行期类型判定 No1: 对于作为程序一部分的每个类,它们都有一个Class对象.换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当的说, ...

  8. JAVA编程思想读书笔记(二)--容器

    接上篇JAVA编程思想读书笔记(一) 第八章.对象的容纳 No1: java提供了四种类型的集合类:Vector(矢量).BitSet(位集).Stack(堆栈).Hashtable(散列表) No2 ...

  9. JAVA编程思想读书笔记(四)--对象的克隆

    接上篇JAVA编程思想读书笔记(三)--RTTI No1: 类的克隆 public class MyObject implements Cloneable { int i; public MyObje ...

随机推荐

  1. 前后端结合的 WAF

    前言 之前介绍了一些前后端结合的中间人攻击方案.由于 Web 程序的特殊性,前端脚本的参与能大幅弥补后端的不足,从而达到传统难以实现的效果. 攻防本为一体,既然能用于攻击,类似的思路同样也可用于防御. ...

  2. python类中的双下划线方法

    __getitem__,__setitem__和__delitem__ 实现了对象属性的字典化操作. class Person: def __init__(self, name, age, hobby ...

  3. 浅谈使用spring security中的BCryptPasswordEncoder方法对密码进行加密与密码匹配

    浅谈使用springsecurity中的BCryptPasswordEncoder方法对密码进行加密(encode)与密码匹配(matches) spring security中的BCryptPass ...

  4. Junit 测试集(打包测试)实例

    测试集,直译过来的意思就是把测试集合起来,再详细一些就是把多个单元测试集合起来 .单元测试可以理解为:单个接口 或者单个类/方法 的测试 项目背景:测试基于spring开发的项目代码 实例模板:pac ...

  5. Linux 内核USB 接口配置

    USB 接口是自己被捆绑到配置的. 一个 USB 设备可有多个配置并且可能在它们之间转换 以便改变设备的状态. 例如, 一些允许固件被下载到它们的设备包含多个配置来实现这个. 一个配置只能在一个时间点 ...

  6. 【31.93%】【codeforces 670E】Correct Bracket Sequence Editor

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  7. IIS 6和IIS 7 中设置文件上传大小限制设置方法,两者是不一样的

    在IIS 6.0中设置文件上传大小的方法,只要设置httpRuntime就可以了 <system.web> <httpRuntime executionTimeout="3 ...

  8. RNN,LSTM

    RNN: Vanilla Neural Network :对单一固定的输入给出单一固定输出 Recurrent Neural Network:对单一固定的输入给出一系列输出(如:可边长序列),例:图片 ...

  9. C++学习——输入输出及头文件

    C++学习 ——输入输出及头文件 一.输入输出 (1)cin与cout C++中也可以用printf与scanf,但是相对于这个,cin与cout更加方便一点.让我们先来看一段代码. 运行结果: 这里 ...

  10. mysql主从之基于mycat实现读写分离

    一 环境 1.1 结构 192.168.132.125 mycat 192.168.132.121  master 192.168.132.122  slave 主从已经配置完成 1.2 安装myca ...