数据都存放在哪里?
1.寄存器。记得以前汇编里面有学习过,叫做register的东西,Java里面接触不到这个。
2.栈。Stack。放在RAM里面,随机存储器用来存储基础类型,例如short int long float double char byte boolean等,或者用来存储对象的引用。
例如:
A a = new A();
A b = a;
A c = a;
这里的b,c都是放在栈里面。
3.堆。Heap,也放在RAM里面,例子里面的a就是放在这里的。凡是new 出来的。。。不过String放在哪里的呢?是不是也放在这里呢?
String s = "abc";//这里"abc"存放在常量存储区,s是引用,所以s在栈里面。
String s2= new String("abc"); //s2是new出来的,所以在堆里面。
String s3 = "abc"+"def"; // 如果"abcdef"已经在常量存储器里面创建了,那么s3就是引用,放入Stack,否则s3就在堆里
4.静态存储区,也在RAM里面。也就是Static声明的字段都放在这里,那Static声明的方法和类是不是也放在这里呢?
5.常量存储区,在ROM,只读存储器。用来放final声明的。
6.非RAM中。例如数据库,例如网络流中,用那种持久化技术存起来就好了。
其实我们可以将上面的6个部分笼统的分为4个,寄存器,栈(包括栈,静态存储区,常量存储区),堆,非RAM。寄存器和非RAM不在我们讨论范围内。只关心栈和堆。
先来段程序。
主程序:
Test t = new Test();
t.see();
具体的类:
class Test{
static int s1=1;
String s2="abc";
public void see(){
int i=0;
System.out.println("see");
}
}
解释一下这段程序,先将主程序指令存入Stack,执行,第一句的时候,在Heap里面为t分配空间,建立对象实例的属性值,属性类型,以及对象本身的类型标记,在Stack里面建立对象的方法。最终将Heap里面t的4字节地址返给Stack中,等到t.see()调用的时候,see()方法默认传个隐藏参数进来,即调用see方法的对象的Heap地址,然后执行。
为什么静态方法不能调用非静态属性?
因为静态方法是最开始load进来的,放在Stack里,可以直接通过栈寻址找到它的,而非静态属性则是存放在Heap里面,只有实例化出具体对象才能存在。
下面转载一篇文章,出处找不到了。。
作者 robbin (http://hibernate.fankai.com/站长)
我试着从JVM的内存管理原理的角度来谈一下静态方法和静态属性的问题,不对的地方请指正。
JVM的内存分为两部分:stack和heap:
stack(栈)是JVM的内存指令区。stack管理很简单,push一定长度字节的数据或者指令,stack指针压栈相应的字节位移;pop一定字节
长度数据或者指令,stack指针弹栈。stack的速度很快,管理很简单,并且每次操作的数据或者指令字节长度是已知的。所以Java基本数据类
型,Java指令代码,常量都保存在stack中。
heap(堆)是JVM的内存数据区。heap的管理很复杂,每次分配不定长的内存空间,专门用来保存对象的实例。在heap中分配一定的内存来保存对象
实例,实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是指令,保存在stack中),在heap中分配
一定的内存保存对象实例和对象的序列化比较类似。而对象实例在heap中分配好以后,需要在stack中保存一个4字节的heap内存地址,用来定位该对
象实例在heap中的位置,便于找到该对象实例。
由于stack的内存管理是顺序分配的,而且定长,不存在内存回收问题;而heap则是随机分配内存,不定长度,存在内存分配和回收的问题;因此在JVM
中另有一个GC进程,定期扫描heap,它根据stack中保存的4字节对象地址扫描heap,定位heap中这些对象,进行一些优化(例如合并空闲内存
块什么的),并且假设heap中没有扫描到的区域都是空闲的,统统refresh(实际上是把stack中丢失了对象地址的无用对象清除了),这就是垃圾
收集的过程。
我们首先要搞清楚的是什么是数据,什么是指令?然后要搞清楚对象的方法和对象的属性分别保存在哪里?
为了便于描述,我简单的统称:
1)方法本身是指令的操作码部分,保存在stack中;
2)方法内部变量作为指令的操作数部分,跟在指令的操作码之后,保存在stack中(实际上是简单类型保存在stack中,对象类型在stack中保存地址,在heap中保存值);
上述的指令操作码和指令操作数构成了完整的Java指令。
3)对象实例包括其属性值作为数据,保存在数据区heap中。
非静态的对象属性作为对象实例的一部分保存在heap中,而对象实例必须通过stack中保存的地址指针才能访问到。因此能否访问到对象实例以及它的非静态属性值完全取决于能否获得对象实例在stack中的地址指针。
先分析一下非静态方法和静态方法的区别:
非静态方法有一个和静态方法很重大的不同:非静态方法有一个隐含的传入参数,该参数是JVM给它的,和我们怎么写代码无关,这个隐含的参数就是对象实例在
stack中的地址指针。因此非静态方法(在stack中的指令代码)总是可以找到自己的专用数据(在heap中的对象属性值)。当然非静态方法也必须获
得该隐含参数,因此非静态方法在调用前,必须先new一个对象实例,获得stack中的地址指针,否则JVM将无法将隐含参数传给非静态方法。
而静态方法无此隐含参数,因此也不需要new对象,只要class文件被ClassLoader load进入JVM的stack,该静态方法即可被调用。当然此时静态方法是存取不到heap中的对象属性的。
总结一下该过程:当一个class文件被ClassLoader
load进入JVM后,方法指令保存在stack中,此时heap区没有数据。然后程序技术器开始执行指令,如果是静态方法,直接依次执行指令代码,当然
此时指令代码是不能访问heap数据区的;如果是非静态方法,由于隐含参数没有值,会报错。因此在非静态方法执行前,要先new对象,在heap中分配数
据,并把stack中的地址指针交给非静态方法,这样程序技术器依次执行指令,而指令代码此时能够访问到heap数据区了。
再说一下静态属性和动态属性:
前面提到对象实例以及动态属性都是保存在heap中的,而heap必须通过stack中的地址指针才能够被指令(类的方法)访问到。因此可以推断出:静态
属性是保存在stack中的(基本类型保存在stack中,对象类型地址保存在stack,值保存在heap中),而不同于动态属性保存在heap中。正
因为都是在stack中,而stack中指令和数据都是定长的,因此很容易算出偏移量,也因此不管什么指令(类的方法),都可以访问到类的静态属性。也正
因为静态属性被保存在stack中,所以具有了全局属性。
总结一下:静态属性保存在stack指令内存区,动态属性保存在heap数据内存区。
分享到:
相关推荐
在 Linux 中,MySQL 数据文件的存放位置默认在 `/var/lib/mysql` 目录下。但是,在某些情况下,我们可能需要将数据文件存放位置修改到其他目录下。这篇文章将会指导您如何在 Linux 中修改 MySQL 数据文件存放位置。 ...
数据在计算机内存中存放的形式是理解程序执行过程的关键部分。内存主要分为几个不同的区域,每种区域都有其特定的用途和管理方式。以下是对这些内存区域的详细解释: 1. 栈区(Stack): 栈区是内存中一块非常重要...
Docker 数据存放路径是指 Docker 容器存放数据的路径,默认情况下,Docker 将数据存放在 `/var/lib/docker` 目录下。然而,这个目录可能位于系统的根分区上,这可能会导致以下问题: * 磁盘空间不足:如果系统的根...
例如,如果你有一个名为`mydb`的数据库,它的数据文件将存放在`data\mydb`目录下。`3.找到数据库.png`可能显示的就是这个过程,演示了如何在Windows资源管理器中找到特定数据库的数据文件。 在`4.文件介绍.png`中,...
8088系统数据存放方式主要涉及微机体系结构中的内存管理和寻址方式。8088处理器是Intel公司的一款16位微处理器,它的内存访问和数据存储方式对于理解和编写汇编语言程序至关重要。 首先,8088系统中的数据在内存中...
已知DATA单元开始存放一组无符号的字节数据,数据长度在CNT单元存放。编制程序,检查该组数据中是否存在数据100,若存在,则在显示器上显示“Y”,否则显示“N”编制在屏幕上显示九九表的程序。已知两个长度相等的带...
Wealth-lab通达信日线数据接口,Wealth-lab通达信日线数据接口
### 浏览器端数据存放技术 #### 一、引言 随着互联网技术的发展与Web应用功能的日益丰富,浏览器端的数据存储技术变得尤为重要。在客户端进行数据存储不仅可以减轻服务器的压力,提高应用性能,还能为用户提供更加...
HashMap 在 put 数据时是如何找到要存放的位置的? 在使用 HashMap 时,我们常常会问自己,HashMap 是如何找到要存放的位置的?答案就在于hashCode的计算方法和数组长度的影响。下面我们将详细解释这个问题。 首先...
### 购物车数据存放方式的深度解析 在电子商务网站开发中,购物车功能是不可或缺的一部分,其设计与实现直接影响用户体验及系统性能。本文基于标题“购物车中数据的存放方式”及其描述,深入探讨两种主要的购物车...
"通过swf实现将数据存放在客户端"的方案是一种利用Adobe Flash技术(SWF文件)和JavaScript(JS脚本)来达到这个目的的方法。尽管现在Flash已经不再被广泛支持,但在过去,它提供了在没有HTML5 localStorage或...
python基础_34_pickle_存放数据_(教学教程tutorial)
微信小程序demo:todo:wx.setStorageSync(KEY,DATA) 方法存放数据(源代码+截图)微信小程序demo:todo:wx.setStorageSync(KEY,DATA) 方法存放数据(源代码+截图)微信小程序demo:todo:wx.setStorageSync(KEY,DATA) ...
当使用MyISAM存储引擎时,数据库文件(包括.frm、.MYD、.MYI)的默认存放位置通常在: ``` C:\Documents and Settings\All Users\Application Data\MySQL\MySQL Server 5.1\data ``` 但实际位置可能因MySQL服务器...
HashMap存放.doc
这是一份汇编语言实验报告,主要内容是使用循环结构编程统计100个学生的某课成绩分数,分为100分、90-99分、80-89分、70-79分、60-69分和59分以下六个分数段,并将结果连续存放在RESULT开始的单元中。实验中使用了...
定制化数据存放方法在电子政务中的应用主要体现在以下几个方面: 1. 数据结构优化:针对电力电子DCS的数据特性,定制化数据存放方法需要考虑数据的实时性、规模和类型。例如,电压、电流等实时参数应快速存取,历史...
基于YOLOV5的水域中游泳者检测识别系统源码+数据集.zip数据集说明数据集存放在项目根路径的 myDataSet 文件夹内在实际训练时,请按照作者要求的目录机构组织数据集的位置,即让数据集和项目位于同级目录下。...
结构体是一种数据的归类方式,相比数组或变量更具有整体全面性,例如一个数组只可以放一些按照元素顺序存放的单元变量,即 buffer = {x, x, x, x, x…},i 有多大,数组内元素就有多少。那么我们这时候如果我们用这...
用Visual C#如何调用Excel,如何又把数据存放到Excel表格中?本文就来探讨一下上述问题的解决办法。 string strCon = " Provider = Microsoft.Jet.OLEDB.4.0 ; Data Source = c:\\sample.xls;Extended Properties=...