内存类型

Redis系列(十)Redis对象系统

让人想犯罪 __ 提交于 2020-02-04 12:18:18
前言 介绍 类型 编码和底层数据结构 五种常见的对象类型 类型检查与命令多态 内存回收 对象共享 对象淘汰:空转时长 总结 参考文章 联系我 前言 其实关于本文,我犹豫再三。 对象系统值得写一篇文章吗?从技术上来讲,当然是值。但是对于我们大部分人来说,它都是隐身的。 写的话,顺序放在哪里?在 Redis 系列(九)底层数据结构之五种基础数据类型的实现 中其实就提到了,那么应该在此之前先介绍它吗? 结论:想那么多屁事,写就完事了。 介绍 正如上一篇文章提到的,Redis 不是生硬的使用前面介绍过的数据结构,来实现了字符串,列表,字典等等数据结构,而是精心打造了一个对象系统。 对于 Redis 来说,所有的所谓的数据类型,本质上都是一个对象,而且同一个类型的对象,底层实现编码不一样。 Redis 对象的定义为: // 类型 typedef type : 4 ; // 编码 unsigned encoding : 4 ; // 指向底层数据结构的指针 void * ptr ; . . . 类型 对象的 type 属性,记录了对象的类型,这个类型就是我们所熟知的 Reids 的数据类型了,比如字符串,列表,集合,有序集合,散列等。 对于 Redis 数据库中的键值对来讲,键值永远是一个字符串对象,值可以是很多种。 编码和底层数据结构 对象的 ptr 指针,指向对象的底层数据结构

8.Go语言基础之指针

元气小坏坏 提交于 2020-02-04 00:27:09
Go语言中的指针不能进行偏移和运算,是安全指针。 在了解GO语言中的指针前,首先需要知道三个概念:指针地址、指针类型和指针取值。 1.Go语言中的指针 任何数据载入内存后,在内存中都有对应的地址,这就是指针。 为了保存一个数据在内存中的地址,需要指针变量。 比如"好好学习,天天向上"这个字符串写入程序中,程序一启动这句话就加载到内存(假设内存地址为0x123456),在程序中,把该字符串赋值给变量A,把该字符串的内存地址赋值给变量B。 这时变量B就是一个指针变量。通过变量A和变量B都能找到该字符串。 Go语言中的指针不能进行偏移和运算,因此Go语言中的指针操作非常简单,只需要记住两个符号:&(取地址)和*(根据地址取值)。 也需要记得: 值类型有:int、float、bool、string、array、struct 引用类型有:指针,map,切片,chan 1.1指针地址和指针类型 每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。 Go语言中使用&字符放在变量前面对变量进行“取地址”操作。 Go语言中的值类型(int,float,bool,string,array,struct)都有对应的指针类型,如*int,*in64,*string等。 取变量指针的语法如下: ptr := &v // v的类型为T 其中: v:代表被取地址的变量,类型为T ptr

[ golang ] golang 语言特性

感情迁移 提交于 2020-02-03 14:00:07
一、golang 语言特性 golang 语言特性主要包括以下几点: q 自动垃圾回收 q 更丰富的内置类型 q 函数多返回值 q 错误处理 q 匿名函数和闭包 q 类型和接口 q 并发编程 q 反射 q 语言交互性 自动垃圾回收 C 语言代码不支持垃圾自动回收,会导致指针存在如下两个问题: void foo() { char * p = new char [128]; ... // 对 p 指向的内存块进行赋值 func1(p); // 使用内存指针 delete [] p; } 1 、各种非预期的原因, 比如由于开发者的疏忽导致最后的 delete 语句没有被调用,都会引发经典而恼人的内存泄露问题。假如该函数被调用得非常频繁,那么我们观察该进程执行时,会发现该进程所占用的内存会一直疯长 ,直至占用所有系统内存并导致程序崩溃,而如果泄露的是系统资源的话,那么后果还会更加严重,最终很有可能导致系统崩溃。 2 、手动管理内存的另外一个问题就是由于指针的到处传递而无法确定何时可以释放该指针所指向的内存块 。假如代码中某个位置释放了内存,而另一些地方还在使用指向这块内存的指针,那么这些指针就变成了所谓的 “ 野指针 ” ( wild pointer )或者 “ 悬空指针 ” ( dangling pointer ),对这些指针进行的任何读写操作都会导致不可预料的后果。 由于其杰出的效率,

python第三章数据类型

☆樱花仙子☆ 提交于 2020-02-03 06:48:20
第三章 数据类型 3.1 整型(int) 3.1.1 整型的长度 py2中有:int有取值范围,对于32位系统而言:-2^31~2^31-1 ​ 对于64位系统而言:-2^63~2^63-1 ​ 超出范围后,py2自动转换成long(长整型)数据。 py3中有:int (int/long)只有int数据. 3.1.2 整除 py2和py3中整除是不一样. py2:整除只保留整数,小数位会舍去.若要保留小数.则在文件头加 from __future__ import division py3整除保留所有. 3.2 布尔(bool) 布尔值就是用于表示真假。True和False。 其他类型转换成布尔值:只有''/0/[]/{}/()/set()转换为bool值为False,其余都是True. 3.3 字符串(str) 字符串是写代码中最常见的 : 单引号,如'王飞' 双引号,如”王大“ 三引号,如“”“王小”“”,三引号支持换行。 注意:整型数据可以+和×,字符串数据也可以+和×。如 name='五五开' new_name=name*3 print(new_name) # '五五开五五开五五开' python内存中的字符串是按照:unicode 编码存储。对于字符串是不可变数据类型。 3.3.1字符串的格式化 字符串格式化的意义,大部分字符过于冗长,使用字符串格式化能大大加快效率

深入理解JVM Note

对着背影说爱祢 提交于 2020-02-02 13:28:40
第2章 Java内存区域与内存溢出异常 运行时数据区域 在虚拟机有栈、堆和方法区。 线程共享的:堆、方法区 不共享的:栈、程序计数器(代码执行的行号) 程序计数器(Program Counter Register): 一小块内存空间,单前线程所执行的字节码行号指示器。字节码解释器工作时,通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。 栈 通常我们定义一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间。 栈是一种线形集合,其添加和删除元素的操作应在同一段完成。栈按照后进先出的方式进行处理。 存在栈中的数据可以共享。假设我们同时定义: int a = 3;  int b = 3; 编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,如果没找到,就开辟一个存放3这个字面值的地址,然后将a指向3的地址。接着处理int b = 3;在创建完b的引用变量后,由于在栈中已经有3这个字面值,便将b直接指向3的地址。这样,就出现了a与b同时均指向3的情况。 StackOverflowError 方法压入和弹出 连续 1.引用类型总是被分配到“堆”上。不论是成员变量还是局部 2.基础类型总是分配到它声明的地方:成员变量在堆内存里,局部变量在栈内存里。 比如

strlen与sizeof区别(转载)

非 Y 不嫁゛ 提交于 2020-02-01 01:49:11
#include "stdio.h" #include "string.h" void main() { char aa[10]; printf("%d",strlen(aa)); printf("%d",sizeof(aa)); } 程序运行得到结果是strlen(aa)=15.sizeof(aa)=10;这是怎么回事呢?strlen是有效字符串的长度,不包含‘\0’,与初始化有关系,而sizeof与初不初始化没有关系。下面我们看看它们的区别吧(以下都是在网上查的) strlen(char*)函数求的是字符串的实际长度,它求得方法是从开始到遇到第一个'\0',如果你只定义没有给它赋初值,这个结果是不定的,它会从aa首地址一直找下去,知道遇到'\0'停止。 char aa[10];cout<<strlen(aa)<<endl; //结果是不定的 char aa[10]={'\0'}; cout<<strlen(aa)<<endl; //结果为0 char aa[10]="jun"; cout<<strlen(aa)<<endl; //结果为3 而sizeof()函数返回的是变量声明后所占的内存数,不是实际长度。 sizeof(aa) 返回10 int a[10]; sizeof(a) 返回40 1.sizeof操作符的结果类型是size_t

c++复合类型

别等时光非礼了梦想. 提交于 2020-02-01 01:04:24
1.数组 数组存储同类型的值; 数组使用下标或索引对元素进行标号,从0开始编号; 只能在定义数组时才能使用初始化,此后就不可以了,也不能将一个数组赋给另一个数组; 初始化数组时,提供的值可以少于数组元素的值。如果只对数组的一部分初始化,则编译器将把其他元素设置为0。因此,将数组中所有元素都初始化为0非常简单——只需显式地将第一个元素初始化为0,然后让编译器将其他元素都初始化为0即可:long totals[500] = {0}. 2.字符串   要将字符串存储到数组中,最常用的方法有两种——将数组初始化为字符串常量、将键盘或文件输入读入到数组中。 3.string类 可以使用c-风格字符串来初始化string对象; 可以使用cin来将键盘输入存储到string对象中; 可以使用cout来显示string对象; 可以使用数组表示法来访问存储在string对象中的字符。   c风格的字符串是用数组存放的,一般要以'\0'结束而c++主要以 string类 代替,更加高效,且不易出错   例如:string str = "123";就是c++的风格;char str[4]="123";就是c风格。string是c++中的关键字,和int,float等等一样, 在c++中,string 定义的变量可以直接存储字符串。在C语言中是没有这种直接存储字符串的变量的。   [ ]里面是4,是因为

Java对象内存表示机制

二次信任 提交于 2020-01-30 04:48:03
前言 在《 openjdk的启动流程 》一文,create_vm方法中 initialize_class ( vmSymbols :: java_lang_Thread ( ) , CHECK_0 ) ; //装载threadClass oop thread_object = create_initial_thread ( thread_group , main_thread , CHECK_0 ) ; //创建第一个thread对象 在《 JVM内存模型 》中探讨过,Java对象在内存中是实例数据和类型数据相分离的,实例数据保存了一个指向类型数据的指针,而虚拟机中用oop-klass二分模型很好的进行实现 。 二分模型 Oop表示Java实例,主要用于表示实例数据,不提供任何虚函数功能,Oop保存了对应Kclass的指针,所有方法调用通过Klass完成并通过Klass获取类型信息,Klass基于C++的虚函数提供对Java多态的支持。Klass作为父类主要职责是描述了类的继承关系。 klass MetaspaceObj #类是作为存放在Metaspace元空间的中类的基类 └───Metadata #内部表示类相关元数据的一个基类 │ └───Klass #普通类模板 │ │ └───ArrayKlass #数组类模板 │ │ │ └───TypeArrayKlass

Python可变类型和不可变类型

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-30 04:36:20
Python3 的六个标准数据类型中: 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组); 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。 1⃣️ 可变类型有list、dict等。不可变类型有str、tuple等。 2⃣️ 当进行修改操作时,可变类型传递的是内存中的地址。也就是说,直接修改内存中的值,并没有开辟新的内存。 3⃣️ 不可变类型被修改时,并没有改变原内存地址中的值,而是开辟一块新的内存,将原地址中的值复制过去,对这块新开辟的内存中的值进行操作。 对不可变数据类型进行修改操作会出现错误。 例如: >>>word = 'Python' >>> print(word[0], word[5]) P n >>> print(word[-1], word[-6]) n P 与 C 字符串不同的是,Python 字符串不能被改变。向一个索引位置赋值,比如word[0] = 'm'会导致错误。 来源: CSDN 作者: hongge_smile 链接: https://blog.csdn.net/hongge_smile/article/details/104107015

【C语言】08-数组

 ̄綄美尐妖づ 提交于 2020-01-30 04:33:08
本文目录 地址 一、一维数组 二、二维数组 说明:这个C语言专题,是学习iOS开发的前奏。也为了让有面向对象语言开发经验的程序员,能够快速上手C语言。如果你还没有编程经验,或者对C语言、iOS开发不感兴趣,请忽略 为了让大家更好地学习和理解数组,我们先来认识一下内存中的"地址"。 回到顶部 地址 1.计算机中的内存是以字节为单位的存储空间。内存的每一个字节都有一个唯一的编号,这个编号就称为地址。凡存放在内存中的程序和数据都有一个地址,也就是说,一个函数也有自己的内存地址。 2.当定义一个变量时,系统就分配一个带有唯一地址的存储单元来存储这个变量。比如: char a = 'A'; // A的ASCII值为65 int b = 66; 在16bit编译器环境下,系统为a、b分别分配1个字节、2个字节的存储单元。变量存储单元的第一个字节的地址就是该变量的地址。 可以看出,变量a的地址是ffc3;变量b的地址是ffc1。内存中存储的都是2进制数据。 3.在调试过程中,我们采取打印的方式查看变量的地址: int c = 10; // 以16进制形式输出地址 printf("16进制:%x\n", &c); // 以10进制形式输出地址 printf("10进制:%d", &c); 输出结果: 回到顶部 一、一维数组 1.一维数组的定义 * 定义的形式为: 类型 数组名[元素个数] int