目录
计算机的存储规则
在计算机当中,一般有三种数据(视频 是图片和声音的组合体)
Text文本 :
数字 --> 二进制 -->储存
字母 --> ASKLL码表 --> 二进制 -->储存
汉字 --> unicode码表 -->二进制 -->储存
Image图片 :
黑白图 灰度图 彩色图 (通过每个像素点中RGB三原色来存储)
图片的存储通过在每个像素点中使用RGB三原色的亮度值来表示颜色。黑白图像的每个像素只有两种可能值,灰度图像的每个像素通过灰度值表示,彩色图像的每个像素通过红、绿、蓝三原色的亮度值的组合表示。分辨率决定了图片的清晰度和细节程度。
说到图片的存储,就要提到显示器的三个知识 : 分辨率 像素 三原色: 红绿蓝(取值范围:0 ~ 255)
分辨率(Resolution):分辨率是指显示器上显示的图像的像素点数量。它通常以水平像素数和垂直像素数来表示,比如1920x1080表示水平有1920个像素,垂直有1080个像素。分辨率决定了图像的清晰度和细节程度,通常情况下,分辨率越高,图像显示越细腻。
像素(Pixel):像素是组成图像的最小单元,每个像素点都有自己的颜色值。一个像素对应显示器上的一个发光点,它可以是红、绿、蓝三原色中的一个或多个的组合。像素的颜色值决定了图像的颜色和亮度。
三原色(RGB):在彩色图像中,每个像素点的颜色是由红、绿、蓝三个基本颜色的亮度组合而成的。每个颜色通道的亮度值范围是0到255,其中0表示最暗,255表示最亮。通过调节三原色的亮度值的组合,可以形成各种颜色。
Sound声音 :
对声音的波形图进行采样再存储
下面研究一下它们在计算机当中是怎么存储的
在计算机当中,任意数据都是以二进制的形式存储的
在我们首次接触计算机时那么就会有疑问:
1. 什么是二进制?
直接说二进制我们可能会有点懵,那么我们先从我们熟悉的生活中常用的十进制说起
十进制 由 0 1 2 3 4 5 6 7 8 9 这十个数字构成,它的计算规则是逢十进一,借一当十
二进制与十进制类似
二进制 由 0 1 这两个数构成, 它的计算规则是逢二进一,借一当二
常见的进制有 二进制, 十进制,八进制(0 ~ 7),十六进制(0 ~ 9 和 a ~ f) 那么我们在代码中写一个数字,怎么知道表示多少呢
所以呢,Java中做了一些规定 ,在代码中以不同的前缀开头(JDK7之后)
二进制(0 1) | 0b |
十进制(0 ~ 9) | 默认,前面不需要加任何前缀 |
八进制(0 ~ 7) | 0 |
十六进制(0 ~ 9 和· a ~ f ) | 0x |
2.计算机为什么使用二进制储存数据呢?
①技术实现简单,计算机是由逻辑电路组成,逻辑电路 通常只有两个状态,开关的接通与断开,这两种状态正好可以用“1”和“0”表示。
②简化运算规则:两个二进制数和、积运算组合各有三种,运算规则简单,有利于简化计算机内 部结构,提高运算速度。
③适合逻辑运算:逻辑代数是逻辑运算的理论依据,二进制只有两个数 码,正好与逻辑代数中的“真”和“假”相吻合。
④易于进行转换,二进制与十进制数易于互相转换。
⑤用二进制表示数据具有抗干扰能力强,可靠性高等优点。因为每位数据只有高低两个状 态,当受到一定程度的干扰时,仍能可靠地分辨出它是高还是低。
3.进制之间可以转换吗?
任意进制十进制 :
公式 :系数 * 基数的权次幂 相加
系数 : 就是每一位上的数
基数 : 当前进制数
权 : 从右往左,依次为0 1 2 3 4 5······
十进制转其他进制
除基取余法
不断的除以基数(几进制,基数就是几)得到余数,直到商为零,再将余数倒着拼起来
java JVM内存分配
在JDK7以前方法区和堆是连在一起的,从JDK8开始,取消了方法区,新增元空间,把原来方法区的多种功能进行拆分,有的功能放入到了堆中,有的功能放入元空间,为了我们方便理解,我们还是叫做方法区
栈 : 方法运行时使用的内存,比如main方法运行,进入方法栈中执行
堆 : 存储对象或者数组,new来创建的,都储存在堆内存
new出来的东西,在这块内存中开辟空间并产生地址值
方法区 :储存可以运行的class文件
本地方法栈 : JVM在使用操作系统功能的时候使用,和我们开发无关
寄存器 : 给CPU使用,和我们开发无关
数组的内存分配
以下是从内存的角度去介绍如何定义一个数组 如何获取数组中的元素 如何给数组赋值
1.main方法入栈
2.执行第一行代码 ,先是等号左边 :在栈里面定义 int[ ] arr;
等号右边: 有new关键字,所以说在堆里面开辟一个小空间,在堆里面空间是有地址值的,所以会通过中间的等号把地址值赋给arr,因此arr可以通过地址值找到堆里面的这个空间;
数组存储跟变量的区别:
定义一个变量时,变量里面存储的是一个真实的数据;因为数组存储的数据可能有很多很多,没有办法把所有的数据存储在arr在给变量当中,所以java在设计的时候,把所有的数据放在另外的一块空间当中,而arr记录的就是那一块空间的地址值;所以往下
2.执行第二条语句,它打印就是变量所记录的地址值
3..执行第3条语句,通过arr找到堆的这块空间,再通过0索引找到了里面的第一个数据,所以打印的值是0
4..执行第4条语句,与3同理,通过arr找到堆的这块空间,再通过1索引找到了里面的对应数据,所以打印的值是0
5..执行第5条语句 : 其实就是将11 赋值给arr的0索引,首先它也要先通过arr找到堆里面的空间,然后再把11赋值给0索引,此时0索引原来的那个值就被盖住了
6..执行第6条语句,与5同理
7.执行第7.8条语句,打印的是修改的索引对应的值
以上是一个数组的内存分配,哪如果有两个或以上的数组会有什么不一样吗?
8.执行第9条语句 是简化的书写方式,它的完整的初始化当中还是有new关键字,所以说同样的它也会在堆里面开辟一块空间,而arr2记录的就是第二个空间的地址值,此时在堆里面就有两块空间,它们是互相独立的两者之间,没有任何影响
9.后面执行的语句与第一个数组同理
只要是new出来的一定在堆里开辟了一个空间,如果new多次,那么在堆里面有多个小空间,每个小空间都有各自的数据
下面我们讨论一个特殊情况
两个数组指向同一个空间的内存图,其中一个数组对应小空间中的值发生了改变,那么其他数组再次访问时都是修改之后的结果了
方法基本内存原理
-
方法调用的基本内存原理:
-
当方法被调用时,会在内存中创建一个称为栈帧(Stack Frame)的数据结构,用于存储方法的返回地址、方法的参数和局部变量等信息。
-
栈帧被存储在栈(Stack)区域中,每个线程都有自己的栈帧,栈采用先进后出的结构。
-
当方法调用结束后,对应的栈帧被销毁,释放相应的内存空间。
-
-
方法传递基本数据类型的内存原理:
-
基本数据类型的值是直接存储在栈中的,当方法传递一个基本数据类型的参数时,实际上是将该值复制给方法的形参。
-
在方法内部对形参进行修改不会影响原始变量的值,因为实际上操作的是两个不同的变量。
-
-
方法传递引用数据类型的内存原理:
-
引用数据类型的变量存储的是对象的引用(内存地址),而不是对象本身。对象本身存储在堆(Heap)中。
-
当方法传递一个引用数据类型的参数时,实际上是将对象的引用复制给方法的形参。
-
在方法内部对形参进行修改会影响原始变量引用的对象,因为实际上操作的是同一个对象。
-
但需要注意的是,如果在方法内部重新分配一个新的对象并将形参指向该对象,原始变量的引用不会受影响。
-
this的内存原理
this的作用:区分局部变量和成员变量
this的本质:代表所在方法调用者的地址值
在Java中,this关键字表示对当前对象的引用。当方法被调用时,会在内存中创建一个栈帧(Stack Frame)用于存储方法的参数和局部变量。在栈帧中,会包含一个指向当前对象的引用,这个引用就是this。
具体来说,this关键字实际上是一个指向当前对象的隐藏参数,它被隐含地传递给方法。在方法内部,可以使用this引用访问当前对象的成员变量和方法。this引用的值是在方法调用时确定的,指向调用该方法的对象。
在内存中,每个对象都有自己的存储空间,包括对象的成员变量和方法。当对象被创建时,成员变量会被分配在堆(Heap)中的对象实例中。而方法则被存储在方法区(Method Area)中。
当使用this关键字访问成员变量或方法时,实际上是通过当前对象的引用(this)来访问对象的成员。this关键字可以看作是对象内部的一个指针,指向对象本身。
需要注意的是,this关键字只能在非静态方法中使用,因为静态方法是属于类的,无法引用对象的成员。在静态方法中不能使用this关键字。
总结起来,this关键字的内存原理是通过在方法调用时隐含地传递当前对象的引用来访问对象的成员变量和方法。这个引用存储在栈帧中,并指向调用该方法的对象。
和