空间数据

进程的虚拟地址空间,堆栈、堆、数据段、代码段

微笑、不失礼 提交于 2019-12-18 15:02:40
上图是进程的虚拟地址空间示意图。 堆栈段:   1. 为函数内部的局部变量提供存储空间。   2. 进行函数调用时,存储“过程活动记录”。   3. 用作暂时存储区。如计算一个很长的算术表达式时,可以将部分计算结果压入堆栈。 数据段(静态存储区):   包括BSS段的数据段,BSS段存储未初始化的全局变量、静态变量。数据段存储经过初始化的全局和静态变量。 代码段:   又称为文本段。存储可执行文件的指令。 堆:   就像堆栈段能够根据需要自动增长一样,数据段也有一个对象,用于完成这项工作,这就是堆(heap)。堆区域用来动态分配的存储,也就是用 malloc 函数活的的内存。calloc和realloc和malloc类似。前者返回指针的之前把分配好的内存内容都清空为零。后者改变一个指针所指向的内存块的大小,可以扩大和缩小,他经常把内存拷贝到别的地方然后将新地址返回。 1、栈区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap):由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。 3、全局区(静态区):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。

栈与队列(Stack and Queue)

蓝咒 提交于 2019-12-18 03:28:08
1.定义      栈:后进先出(LIFO-last in first out):最后插入的元素最先出来。   队列:先进先出(FIFO-first in first out):最先插入的元素最先出来。 2.用数组实现栈和队列 实现栈:   由于数组大小未知,如果每次插入元素都扩展一次数据(每次扩展都意味着构建一个新数组,然后把旧数组复制给新数组),那么性能消耗相当严重。   这里使用贪心算法,数组每次被填满后,加入下一个元素时,把数组拓展成现有数组的两倍大小。   每次移除元素时,检测数组空余空间有多少。当数组里的元素个数只有整个数组大小的四分之一时,数组减半。   为什么不是当数组里的元素个数只有整个数组大小的二分之一时,数组减半?考虑以下情况:数组有4个元素,数组大小为4个元素空间。此时,加一个元素,数组拓展成8个空间;再减一个元素,数组缩小为4个空间;如此循环,性能消耗严重。   具体代码(Java):    public ResizingArrayStackOfStrings() { s=new String[1]; int N = 0; } pubilc void Push(String item) { //如果下一个加入元素超出数组容量,拓展数组 if(N == s.length) Resize(2 * s.length); s[N++] = item; }

知识点八:二分查找(上)

ⅰ亾dé卋堺 提交于 2019-12-18 02:27:57
前言 二分查找(Binary Search)算法,也叫折半查找算法,是一种非常简单的查找算法,很多非计算机专业的同学很容易就能理解,但是看似越简单的东西往往越难掌握好,想要灵活应用就更加困难。 老规矩,我们还是来看一道思考题:假设我们有 1000 万个整数数据,每个数据占 8 个字节,如何设计数据结构和算法,快速判断某个整数是否出现在这 1000 万数据中? 我们希望这个功能不要占用太多的内存空间,最多不要超过 100MB,你会怎么做呢? 二分思想 二分查找是一种非常简单易懂的快速查找算法,生活中到处可见。比如说,我们现在来做一个猜字游戏。我随机写一个 0 到 99 之间的数字,然后你来猜我写的是什么。猜的过程中,你每猜一次,我就会告诉你猜的大了还是小了,直到猜中为止。那么如何快速猜中我写的数字呢? 假设我写的数字是 23,你可以按照下面的步骤来试一试(如果猜测范围的数字有偶数个,中间数有两个,就选择较小的那个)。 可以看出,只需要7 次就猜出来了,是不是很快?这个例子用的就是 二分思想 ,按照这个思想,即便我让你猜的是 0 到 999 的数字,最多也只要 10 次就能猜中。不信的话,你可以试一试。 回到实际的开发场景中。假设有 1000 条订单数据,已经按照订单金额从小到大排序,每个订单金额都不同,并且最小单位是元。我们现在想知道是否存在金额等于 19 元的订单。如果存在

Java深入剖析之JVM

可紊 提交于 2019-12-17 05:56:05
Java运行时数据区: Java虚拟机在执行Java程序的过程中会将其管理的内存划分为若干个不同的数据区域,这些区域有各自的用途、创建和销毁的时间,有些区域随虚拟机进程的启动而存在,有些区域则是依赖用户线程的启动和结束来建立和销毁。Java虚拟机所管理的内存包括以下几个运行时数据区域,如图: 1、程序计数器:指向当前线程正在执行的字节码指令。线程私有的。 2、虚拟机栈:虚拟机栈是Java执行方法的内存模型。每个方法被执行的时候,都会创建一个栈帧,把栈帧压人栈,当方法正常返回或者抛出未捕获的异常时,栈帧就会出栈。 (1)栈帧:栈帧存储方法的相关信息,包含局部变量数表、返回值、操作数栈、动态链接 a、局部变量表:包含了方法执行过程中的所有变量。局部变量数组所需要的空间在编译期间完成分配,在方法运行期间不会改变局部变量数组的大小。 b、返回值:如果有返回值的话,压入调用者栈帧中的操作数栈中,并且把PC的值指向 方法调用指令 后面的一条指令地址。 c、操作数栈:操作变量的内存模型。操作数栈的最大深度在编译的时候已经确定(写入方法区code属性的max_stacks项中)。操作数栈的的元素可以是任意Java类型,包括long和double,32位数据占用栈空间为1,64位数据占用2。方法刚开始执行的时候,栈是空的,当方法执行过程中,各种字节码指令往栈中存取数据。 d、动态链接

还搞不懂JVM默认垃圾回收器工作原理?那就仔细看看大牛总结的笔记

谁都会走 提交于 2019-12-17 02:11:52
本文转载自 还搞不懂JVM默认垃圾回收器工作原理?那就仔细看看大牛总结的笔记 垃圾回收(GC)是一种对程序中不再使用的内存空间进行自动回收并复用的方式。有别于其它需要手动创建和销毁对象的编程语言,因为GC机制的存在,Java开发人员不需要检查每个对象是否必需的。相反,强大的GC进程会在背后默默丢弃无用的对象,并对剩余的对象进行整理。这种机制使得程序运行时效率更高。 一. 什么是垃圾回收? JVM使用对象形式来组织程序数据。对象会包含若干域(数据),这些数据存在名为heap的托管地址空间中。 考虑一个二叉树节点类定义: class TreeNode { public TreeNode left, right; public int data; TreeNode(TreeNode l, TreeNode r, int d) { left = l; right = r; data = d; } public void setLeft(TreeNode l) { left = l; } public void setRight(TreeNode r) { right = r; } } 假设对该类进行以下操作: TreeNode left = new TreeNode(null, null, 13); TreeNode right = new TreeNode(null, null, 19)

数组

十年热恋 提交于 2019-12-16 22:08:38
数组 数组定义:是一个变量,存储相同数据类型的一组数据,在内存空间划出一串连续的空间 基本要素 标识符:数组的名称,用于区分不同的数组 数组元素:向数组中存放的数据 元素下标:对数组元素进行编号 从0开始,通过下标可以访问到其中的每个元素 元素类型:数组元素的数据类型 使用步骤 声明数组 分配空间 赋值 处理数据 排序 冒泡排序 Arrays.sort(数组名); 插入 来源: CSDN 作者: 我是超级小白 链接: https://blog.csdn.net/lady88888888/article/details/103570565

云数据库MongoDB版清理oplog日志和compact命令详解

依然范特西╮ 提交于 2019-12-16 14:21:00
1、问题描述: 今天看到公司mongodb的oplog有点大,看到云数据库MongoDB版日志清理策略。 MongoDB数据库在长期频繁地删除/写入数据或批量删除了大量数据,将产生很多物理空间碎片。 这些碎片将占用磁盘空间,降低磁盘利用率。 您可以对集合中的所有数据和索引进行重写和碎片整理,释放未使用的空间,提升磁盘利用率和查询性能。 下图说明: 2、前提条件 mongo实例的存储引擎为WiredTiger。 3、详细信息 用户禁止使用 db.repairDatabase 命令。 日志占用空间过大时,会触发自动清理策略。 4、注意事项 执行该操作前,建议对数据库进行备份 执行该操作会导致集合所属的数据库被锁定,且该数据库的读写操作将被阻塞,请在业务低峰期操作。 说明:执行物理空间回收命令(compact)所需的时间与集合数据量、系统负载等因素有关。 5、remove与drop的区别 MongoDB 里删除一个集合里所有文档,有两种方式 db.collection.remove({}, {multi: true}) ,逐个文档从 btree 里删除,最后所有文档被删除,但文件物理空间不会被回收 db.collection.drop() 删除集合的物理文件,空间立即被回收 multi:可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true

RAID技术全解图解-RAID0、RAID1、RAID5、RAID100【转】

怎甘沉沦 提交于 2019-12-16 14:09:34
图文并茂 RAID 技术全解 – RAID0、RAID1、RAID5、RAID100……   RAID 技术相信大家都有接触过,尤其是服务器运维人员,RAID 概念很多,有时候会概念混淆。这篇文章为网络转载,写得相当不错,它对 RAID 技术的概念特征、基本原理、关键技术、各种等级和发展现状进行了全面的阐述,并为用户如何进行应用选择提供了基本原则,对于初学者应该有很大的帮助。 一、RAID 概述   1988 年美国加州大学伯克利分校的 D. A. Patterson 教授等首次在论文 “A Case of Redundant Array of Inexpensive Disks” 中提出了 RAID 概念 [1] ,即廉价冗余磁盘阵列( Redundant Array of Inexpensive Disks )。由于当时大容量磁盘比较昂贵, RAID 的基本思想是将多个容量较小、相对廉价的磁盘进行有机组合,从而以较低的成本获得与昂贵大容量磁盘相当的容量、性能、可靠性。随着磁盘成本和价格的不断降低, RAID 可以使用大部分的磁盘, “廉价” 已经毫无意义。因此, RAID 咨询委员会( RAID Advisory Board, RAB )决定用 “ 独立 ” 替代 “ 廉价 ” ,于时 RAID 变成了独立磁盘冗余阵列( Redundant Array of

共享内存

核能气质少年 提交于 2019-12-16 01:59:12
采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。对于像管道和消息队列等通信方式,则需要在内核和用户空间进行四次的数据拷贝,而共享内存则只拷贝两次数据[1]:一次从输入文件到共享内存区,另一次从共享内存区到输出文件。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,再重新建立共享内存区域。而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件。共享内存中的内容往往是在解除映射时才写回文件的。因此,采用共享内存的通信方式效率是非常高的。 Linux的2.2.x内核支持多种共享内存方式,如mmap()系统调用,Posix共享内存,以及系统V共享内存。linux发行版本如Redhat 8.0支持mmap()系统调用及系统V共享内存,但还没实现Posix共享内存,本文将主要介绍mmap()系统调用及系统V共享内存API的原理及应用。 一、内核怎样保证各个进程寻址到同一个共享内存区域的内存页面 1、page cache及swap cache中页面的区分:一个被访问文件的物理页面都驻留在page cache或swap cache中,一个页面的所有信息由struct page来描述。struct page中有一个域为指针mapping ,它指向一个struct address

Kafka高吞吐低延迟原理

三世轮回 提交于 2019-12-15 17:54:30
Kafka基于磁盘做的数据存储,如何实现高性能、高吞吐、低延时? Reference: http://searene.me/2017/07/09/Why-is-Kafka-so-fast/ and https://queue.acm.org/detail.cfm?id=1563874 . 顺序读写   Kafka将消息记录持久化到本地磁盘中,实际上不管是内存还是磁盘,快或慢关键在于寻址的方式,磁盘分为顺序读写与随机读写,内存也一样分为顺序读写与随机读写。基于磁盘的随机读写确实很慢,但磁盘的顺序读写性能却很高。   Kafka使用磁盘顺序读写来提升性能,Kafka的message是不断追加到本地磁盘文件末尾的,而不是随机的写入,这使得Kafka写入吞吐量得到了显著提升 。每一个Partition其实都是一个文件 ,收到消息后Kafka会把数据插入到文件末尾。   这种方法不能删除数据 ,所以Kafka是不会删除数据的,它会把所有的数据都保留下来,每个消费者(Consumer)对每个Topic都有一个offset用来表示 读取到了第几条数据 。 两个消费者,Consumer1有两个offset分别对应Partition0、Partition1(假设每一个Topic一个Partition);Consumer2有一个offset对应Partition2