-
2021-02-12 20:49:43
问题一:
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true
问题二:
String str1 =new String ("abc");
String str2 =new String ("abc");
System.out.println(str1==str2); // false
问题三:
String s1 = "ja";
String s2 = "va";
String s3 = "java";
String s4 = s1 + s2;
System.out.println(s3 == s4);//false
System.out.println(s3.equals(s4));//true
由于以上问题让我含糊不清,于是特地搜集了一些有关java内存分配的资料,以下是网摘:
Java 中的堆和栈
Java把内存划分成两种:一种是栈内存,一种是堆内存。
在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。
当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
堆内存用来存放由new创建的对象和数组。
在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。
在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。
引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。
具体的说:
栈与堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象句柄。
栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:
int a = 3;
int b = 3;
编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。
String是一个特殊的包装类数据。可以用:
String str = new String("abc");
String str = "abc";
两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。
而第二种是先在栈中创建一个对String类的对象引用变量str,然后查找栈中有没有存放"abc",如果没有,则将"abc"存放进栈,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。
比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==,下面用例子说明上面的理论。
方式一:
String str1 = "abc";
String str2 = "abc";
System.out.println(str1==str2); //true
可以看出str1和str2是指向同一个对象的。
方式二:
String str1 =new String ("abc");
String str2 =new String ("abc");
System.out.println(str1==str2); // false
用new的方式是生成不同的对象。每一次生成一个。
因此用第一种方式创建多个”abc”字符串,在内存中其实只存在一个对象而已. 这种写法有利与节省内存空间. 同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。
另一方面, 要注意: 我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为,创建了String类的对象str。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的对象。只有通过new()方法才能保证每次都创建一个新的对象。由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率。
更多相关内容 -
易语言内存基址搜索
2020-07-22 03:11:43易语言内存基址搜索源码,内存基址搜索,内存搜索,模块内存地址,模块内存搜索,地址是否存在,GetRead,读内存小数型,读内存整数型,写内存整数型,读内存文本型,写内存文本型,读内存字节集,十到十六,搜索地址,搜索线程,... -
内存地址
2019-09-14 18:26:56滴水逆向三期:内存地址 复习: 1.32位 16位 8位寄存器 每个容器是有宽度的,宽度决定装多少东西,在计算机世界里有数据宽度 EAX ECX EDX EBX ESP EBP ESI EDI AX CX DX BX SP BP SI DI AL CL DL BL AH CH DH BH 2,...滴水逆向三期:内存地址
复习:
1.32位 16位 8位寄存器
每个容器是有宽度的,宽度决定装多少东西,在计算机世界里有数据宽度
EAX ECX EDX EBX ESP EBP ESI EDI
AX CX DX BX SP BP SI DI
AL CL DL BL AH CH DH BH
2,寄存器结构EAX-AX-AL
他们三个是包含的关系 上个文章有图这些寄存器并不是独立存在的 地位高位 EAX低位的部分AX AX本身就在EAX里 EAX的一半就是AX AX再分成AH AL AH再AX的高位,AL再AX的低位,他们都是EAX的一部分 往下都是这样
例如:
mov eax,0XAAAAAAAA mov ax,0xBBBB mov ah,0xDD mov al,0xEE
F8后就变成了AAAADDEE
3.为什么8位寄存器只能放2个十六进制数
寄存器事8位的 存8个0和1 最大的宽度就是8个0和1 1个16进制数需要4位二进制 所以8位刚好可以存放2个16进制数 16位4位16进制 32位8位16进制
4.内存单元,字节,每个字节有个编号,称为内存地址
32位计算机的寻址宽度是32位,一共有32个情况就是8个0找到8个F 一个8位的就是一个编号,因为内存太多了只能用编号来说,每个编号对应一块内存,每个内存编号对应是一个字节
左边是数据窗口,右边是堆栈窗口
因为我们的任何一个程序总归都是数据来表示的,我们通过数据这个窗口可以更好的去了解内存的编号
内存编号:内存编号之间相差4个字节,一个字节是8位
db 0x12FFDC
为什么后面的数据不一样的,前面不都是内存编号?数据在存储的时候,在反汇编窗口和寄存器窗口,顺序是从高到低
而在数据窗口是从低到高,前面是低后面是高,内存中最小的存储单位是字节,一个16进制数是4位2进制,2个十六进制是1个字节 B6 B3 7C E4
d:查看数据 b:以字节的方式来显示后面数据 dd就相当于dword
0x12FFDC 对应的是位置是E4 ~~~DD 对应是7C往后以此类推
发现宽度不一样所以不允许我们写改一下:
F8后发现变成了0012FFAA(byte对应了一个字节)
word对应了两个字节,而不说一个地址编号对应了一个字节,所以D9收到了牵连
dword4个字节在反汇编窗口数据是从高到低的,在堆栈的窗口顺序是从高到低的,而在数据窗口将会变成78 56 34 12
内存
如果想在计算机里读某块内存和改某块内存最最关键的是什么?
找到内存
这些东西总归就是个编号,比如这个 [ECX+EAX*2]就是ECX的值加上EAX乘2的值,他们两个的结果就是我们要找的那个地址的编号,以后我们看到这个就知道,这个就是个一种地址的编号的表示形式仅此而已
计算机到底可以认识多少种这样的寻址方式,是给个数找还是通过寄存器一共认识几种呢?
MOV EAX,DWORD PTR DS:[0x13FFC4]出来的时候有C4 C5 C6 C7 把内存中的数据放到寄存器里,MOV不可以把内存放到内存里,不能同时为内存单元
MOV DWORD PTR DS:[0x13FFC4],eax把寄存器里的值放到内存里
LEA EAX,DWORD PTR DS:[0X13FFC4] MOV的话就是把C4后面的那几个和C4的值放到EAX中
内存编号 对应的值
写一个MOV EAX,DWORD PTR DS:[0x13FFC4]和LEA EAX,DWORD PTR DS:[0x13FFC4] F8后看到了把7C82F23B就放到了EAX中这个是MOV的命令,而经过LEA的命令后EAX的值变成了前面的内存编号的值,现在可能有个疑问,我们后面都写了0x13FFC4的地址还有放还有什么用?后面会涉及到间接寻址的,这个[]里面的值不是确定的值,他可能随时在变可能是某个寄存器存着的值,如果这个不是固定的值,那么这个LEA就很有用了
基址 MOV EAX,DWORD PTR DS:[ECX]在这里我们并不是把ECX的值读出来,而是把ECX的值看成了一个地址编号,把这个地址编号指向的内存的值读出来
F8:把12FFC4的值放进ECX里 再F8:把ECX就相当于12FFC4 然后把对应的内存读出来
读数据和上面的原理相同
LEA EAX,DWORD PTR DS:[ECX]
执行的时候在EAX存的是ECX的地址编号C4 0012FFC4
先放到ECX中,然后我们读取的是C4+4 C8:都是0这种
LEA取的是编号的值C4+8:CC
mov是找内存把内存里的值拿出来而lea他就是把内存的编号(内存地址)的值取出来
reg:任何一个通用的32位寄存器任何一个都可以[1,2,4,8]是不能变的,因为因特尔的工作室这五种格式超过这五种他解释不了,这就是为什么寻址公示只能用这五种
像第一个就是EAX+8 EAX+ECX*4这就是编号拼起来的结果就是一个编号
如果说结果超过了FFFFFFFF如果变成了9个F 如果一旦超过他只取8个F别的就不要了,这种地址编号一般是通过高级语言编译过来的,编译过来的时候是不可能超过8个F的
同上的原理—— 2019.9.14 DT
-
Python 如何查看内存地址
2021-07-16 22:29:48python 查看内存地址很简单,使用内置函数id 下面看下使用 a = 1024 print("a的内存地址为:%s" % id(a)) b = 1024 print("b的内存地址为:%s" % id(b)) 打印结果: 额外补充: 在python 中允许多个变量指向同一...python 查看内存地址很简单,使用内置函数id
下面看下使用
a = 1024 print("a的内存地址为:%s" % id(a)) b = 1024 print("b的内存地址为:%s" % id(b))
打印结果:
额外补充:
在python 中允许多个变量指向同一个值,例如
a=b=1024 ,这个是允许的, 但是在c++ 中是不存在这种写法的,有意思吧.
-
虚拟内存和地址空间
2021-05-26 17:30:37现代计算机为提高CPU使用率、并发执行多个程序、隔离程序间内存地址、打破物理内存上限,采用虚拟内存机制来运行程序 一、物理内存vs虚拟内存 物理内存就是实实在在的内存条。 虚拟内存是一个概念,对于一个程序...目录
早期的计算机程序都是直接跑在物理内存上的,这就要求程序大小不能超过物理内存的上限;
现代计算机为提高CPU使用率、并发执行多个程序、隔离程序间内存地址、打破物理内存上限,采用虚拟内存机制来运行程序
一、物理内存vs虚拟内存
物理内存就是实实在在的内存条。
虚拟内存是一个概念,对于一个程序来说,它包含了程序运行时可用的内存空间总和,包括共享的、非共享的、物理内存中的、存在分页中的等等。【虚拟内存映射 = 物理空间 + 硬盘空间 + 未使用的映射】
二、物理内存空间和虚拟内存空间
物理内存大小组成的地址空间就是物理内存空间。就是我们常说的RAM物理内存空间。可以看成一个连续的M个字节大小的数组。每个字节对应唯一的物理地址。
虚拟内存大小组成的地址空间就是虚拟内存空间。和物理内存空间一样,它也有地址空间。
三、32bit的地址空间
32位的操作系统为一个新创建的程序,分配一个4GB(2^32)大小的虚拟内存。这个过程就是创建了一个映射表,并不是真正的分配到物理内存上。
四、cpu位宽和cpu地址总线宽
虚拟内存的大小与实际的RAM没有关系,而是取决于cpu位宽 和 cpu地址总线宽
1、我们平时说的32位的cpu、64位的cpu ,指的就是cpu的位宽,表示的是一次能够处理的数据宽度。即一个时钟周期内cpu能够处理的2进制位数。其取决于寄存器的宽度
2、cpu地址总线宽度决定了直接寻址物理内存空间。如果cpu的地址总线是32位的,也就是它可以寻址 0 - 0xFFFFFFFF (4G)的物理地址。
3、cpu位宽 不等于 cpu地址总线宽度 。 16位的cpu的地址总线宽可以是20位
4、cpu访问任何存储单元必须知道其物理地址,所以在一定程序上,cpu总线宽影响了最大支持的RAM大小
五、虚拟内存地址空间划分
预留空间:从0x00000000到0x08048000的这段空间是预留的,是不能访问的,例如对空指针进行访问程序就会崩溃
只读段:程序运行时产生的指令放在此分段。同时这一段也保存了只读数据
.data读写段:存放初始化了且初始化值不为0的数据
.bss读写段:存放了未初始化 或 初始化值为0的数据
运行时堆:这段时间是不存在的,只有当程序运行起来后,new 或者 malloc之后才会分配内存,由低地址向搞地质增长
加载共享库:动态链接库,windows下是*.dll,Linux下是 *.so
stack : 函数或者线程都有独立的栈空间,由高地址向低地址增长
命令行参数和环境变量,命令行参数如main函数传参,环境变量如搜索头文件、库文件时默认的路径
六、虚拟地址和物理地址的映射
一个程序想要运行,必须运行在真实的物理内存之上,所以必须在虚拟内存地址和物理内存地址之间建立一种映射关系。
这种映射关系是由操作系统建立的,当程序访问虚拟地址的一个地址时,实际上是通过映射关系访问了真实内存的另外一个地址值。
这种映射机制需要硬件的支持——cpu中的内存管理单元(Memory Management Unit , MMU)利用存放在物理内存中的映射表动态翻译,这就是cpu虚拟寻址。
当程序试图访问地址空间的一个地址位置时,我们通过以下的假代码表示以下:
if(数据在物理内存中) { 虚拟地址转换成物理地址 读数据 } else { if(数据在磁盘中) { if(物理内存还有空闲) { 把数据从磁盘中读到物理内存 虚拟地址转换成物理地址 读数据 } else { 把物理内存中某页的数据存入磁盘 把要读的数据从磁盘读到该页的物理内存中 虚拟地址转换成物理地址 读数据 } } else { 报错 } }
-
操作系统虚拟内存和地址映射
2021-08-11 09:26:45在程序装入的时候,可以将程序中很快会用到的部分先装入内存,暂时用不到的部分放在外存,就可以让程序开始执行。 在程序执行过程中,如果需要用到的信息不在内存中,由操作系统负责将所需信息从外村调入内存,... -
查看变量内存地址的Python内置函数是____
2021-01-12 03:16:40查看变量内存地址的Python内置函数是____答:id()产妇乳汁分泌主要依赖于答:哺乳时吸吮刺激下列选项中,属于“路径面板”中的工具按钮的是答:用前景色填充路径 用画笔描边路径 将路径作为选区载入 从选区生成工作... -
内存地址的概念和理解
2019-05-29 09:07:241.内存地址用4位16进制和8位16进制表示的区别。例如经常可以看到某些书籍上写的内存地址0x0001,在另外一些书籍上写的内存地址又变成了0x00000001。都是表示的编号为1的内存地址,为什么一个是4位16进制表示,另外一... -
关于内存地址和内存空间的理解
2019-08-28 09:39:471.内存地址用4位16进制和8位16进制表示的区别。例如经常可以看到某些书籍上写的内存地址0x0001,在另外一些书籍上写的内存地址又变成了0x00000001。都是表示的编号为1的内存地址,为什么一个是4位16进制表示,另外一... -
C++内存地址分配和内存区划分简介
2018-02-07 11:58:49C++内存地址分配和内存区划分简介 原文地址:http://blog.csdn.net/liuhuiyi/article/details/7530137 内存类型简介 内核:在一些系统中,当系统调用发生时,操作系统或者操作系统内核会编程应用程序内存的一... -
虚拟地址与虚拟内存的理解
2019-04-16 10:38:00在最开始看书的时候,我知道程序在运行时,不是全部加入内存当中的,当然,这个现在依旧正确,在有了虚拟地址空间这个概念以后,我一直认为是在硬盘中划分出一块虚拟内存出来,然后给每个程序4G的硬盘空间,作为这个... -
关于内存和内存地址的详解
2018-10-24 22:48:46内存地址用4位16进制和8位16进制表示的区别。例如经常可以看到某些书籍上写的内存地址0x0001,在另外一些书籍上写的内存地址又变成了0x00000001。都是表示的编号为1的内存地址,为什么一个是4位16进制表示,另外一个... -
Linux 内存管理 详解(虚拟内存,进程地址空间)
2022-04-16 10:06:19Linux -操作系统内存管理存储系统存储器的层次结构Linux的内存管理物理内存物理内存管理虚拟内存虚拟地址空间(写时拷贝)和物理地址映射关系 -
内存地址、机器码与汇编指令的三角恋关系
2020-03-22 18:12:51虽然机器码和内存地址领证在一起了,但是俩个人都和汇编指令有着说不清的关系,机器码的前任是汇编指令,而汇编指令又与内存地址暗地相通,这究竟是道德的沦丧还是人性的扭曲,今天就让我来领大家细细分解这三者的... -
03、指针(内存地址)
2022-04-09 15:53:12文章目录1、指针(内存地址)1.1、概念1.2、获取变量的地址(指针)1.3、一切都是地址1.4、通过地址获取对应的值2、指针变量2.1、定义指针变量2.2、通过指针变量取得数据2.3、通过指针修改数据3、多级指针4、指针运算5、... -
详解:物理地址,虚拟地址,内存管理,逻辑地址之间的关系
2017-11-11 21:27:45物理地址:这里说的物理地址是内存中的内存单元实际地址,不是外部总线连接的其他电子元件的地址!物理地址属于比较好理解的,物理地址就是内存中每个内存单元的编号,这个编号是顺序排好的,物理地址的大小决定了... -
关于内存地址与内存空间的理解
2020-04-07 16:01:321.内存地址 内存地址只是一个编号,代表一个内存空间.具体多大呢?在计算机中存储器的容量是以字节为基本单位的。也就是说一个内存地址代表一个字节(8bit)的存储空间。 例如,32位的CPU理论最多支持4GB的内存空间,... -
内存地址空间布局
2018-03-04 23:55:56http://blog.csdn.net/woshinia/article/details/41722085在多任务...1 32位虚拟内存布局在32位模式下虚拟地址空间总是一个4GB的内存地址块。这些虚拟地址通过页表(page table)映射到物理内存,页表由操作系统维护... -
Linux 内存管理 | 地址映射:分段、分页、段页
2020-12-16 21:57:51文章目录分页分段段页Linux内存管理 分页 分段 段页 Linux内存管理 -
彻底搞懂虚拟内存,虚拟地址,虚拟地址空间
2021-04-27 18:20:55可执行文件由操作系统加载到内存中,交由CPU去执行,现在问题来了,CPU怎么去访问代码和数据?,访问的方式经历过四个阶段: 1.直接访问 2.段基址+段偏移地址 3.段选择子+段偏移地址 4.虚拟地址 现代操作系统采用... -
内存地址与变量值的关系
2019-09-29 09:41:28内存位置与value的关系: id相等的变量,值一定相等,指向的是同一个内存地址;值相等的变量,id不一定相等。 转载于:https://www.cnblogs.com/ludundun/p/11265671.html... -
hashcode和内存地址的关系
2021-03-26 11:28:22疑问:之前一直以为hashcode就是计算对象的内存地址,但是看其它博文又有说不是的,特此研究一下! 先说结论:在JDK1.8中,hashcode和对象的内存地址没有必然关系 代码: 运行结果: 64545 64545 false 也... -
【计算机系统】 信息在计算机中的表示和内存地址与空间的简单理解
2020-07-17 16:17:401. 信息在计算机系统中的表示 ...由于计算机内是采用二进制编码表示,因此,在一般情况下,我们用“0”表示正号,“1”表示符号,符号位数放在数的最高位。 例如,比如我们有十进制数A= +91,B= -91,8位二. -
易语言内存读写支持库2.3 带驱动读写 支持x64进程 静态编译
2021-06-25 15:10:39新增 特征码搜索2 支持通配符搜索 返回十六进制文本内存地址 新增 读二叉树 新增 读文本型Ex 新增 写文本型Ex 新增 读字节集Ex 新增 写字节集Ex 修改 读代码 如:"10007AFA8+50+14" 地址中允许带模块名(模块名要用尖... -
内存管理(指令,地址,装入,链接等)
2020-09-22 17:25:58内存的基础知识什么是内存,有何作用存储单元内存地址进程运行的基本原理,内存起到什么作用指令的工作原理逻辑地址vs物流地址(绝对地址)从写程序-->程序运行三种链接方式三种装入方式 什么是内存,有何作用 ... -
理解内存地址
2018-05-27 10:36:53内存地址:在内存空间中描述位置的方法 物理内存地址:无符号的整数编号,以byte划分,从0开始编号,逐渐线性增大 硬编码:通过物理地址操作物理内存的写码方式 线性内存和线性地址线性内存和物理内存: 相似点:... -
pcie内存地址空间/配置地址空间/io地址空间分析
2020-07-02 08:49:17pci设备与其它接口的设备(如i2c设备)最大的不同是存在内存地址空间和配置地址空间,本文分析一下它们的用途。 首先区分一下IO空间和内存空间 cpu会访问的设备一般有内存和外设寄存器,如下图所示。x86架构采用独立... -
内存地址存储,内存空间
2018-05-13 11:56:37关于内存地址和内存空间的理解。1.内存地址用4位16进制和8位16进制表示的区别。例如经常可以看到某些书籍上写的内存地址0x0001,在另外一些书籍上写的内存地址又变成了0x00000001。都是表示的编号为1的内存地址,为... -
物理地址、虚拟地址、逻辑地址、线性地址、虚拟内存
2017-04-13 15:55:04在实地址模式(因为实模式没有分段或分页机制,Cpu不进行自动地址转换)下,程序员操作的就是物理地址,所谓的物理地址就是物理内存上的32位地址,即物理地址可以直接定位到物理内存上的位置,无论任何操作,最终都必须要...