内存基础

知识图谱——Neo4j介绍 一、引言 在计算机科学中,图形作为一种特定的数据结构,用于表达数据之间的复杂关系,如社交关系、组织架构、交通信息、网络拓扑等等。在图计算中,基本的数据结构表达式是:G=(V,E),V=vertex(节点),E=edge(边)。图形结构的数据结构一般以节点和边来表现,也可以在节点上增加键值对属性。图数据库是 NoSQL(非关系型数据库)的一种,它应用图形数据结构的特点(节点、属性和边)存储数据实体和相互之间的关系信息。 Neo4j 是当前较为主流和先进的原生图数据库之一,提供原生的图数据存储、检索和处理。 阅读详情
在C和C++语言开发中,指针、内存一直是学习的重点。因为C语言作为一种偏底层的中低级语言,提供了大量的内存直接操作的方法,这一方面使程序的灵活度最大化,同时也为bug埋下很多隐患。

  因此,无论如何,我们都要对内存有一个清晰的理解。

  一、对内的分配

  32位操作系统支持4GB内存的连续访问,但通常把内存分为两个2GB的空间,每个进程在运行时最大可以使用2GB的私有内存(0x00000000—0x7FFFFFFF)。即理论上支持如下的大数组:

char szBuffer[2*1024*1024*1024];

  当然,由于在实际运行时,程序还有代码段、临时变量段、动态内存申请等,实际上是不可能用到上述那么大的数组的。

  至于高端的2GB内存地址(0x80000000—0xFFFFFFFF),操作系统一般内部保留使用,即供操作系统内核代码使用。在Windows和Linux平台上,一些动态链接库(Windows的dll,Linux的so)以及ocx控件等,由于是跨进程服务的,因此一般也在高2GB内存空间运行。

  可以看到,每个进程都能看到自己的2GB内存以及系统的2GB内存,但是不同进程之间是无法彼此看到对方的。当然,操作系统在底层做了很多工作,比如磁盘上的虚拟内存交换(请看下以标题),不同的内存块动态映射等等。

  二、虚拟内存

  虚拟内存的基本思想是:用廉价但缓慢的磁盘来扩充快速却昂贵的内存。在一定时刻,程序实际需要使用的虚拟内存区段的内容就被载入物理内存中。当物理内存中的数据有一段时间未被使用,它们就可能被转移到硬盘中,节省下来的物理内存空间用于载入需要使用的其他数据。

  在进程执行过程中,操作系统负责具体细节,使每个进程都以为自己拥有整个地址空间的独家访问权。这个幻觉是通过“虚拟内存”实现的。所有进程共享机器的物理内存,当内存使用完时就用磁盘保存数据。在进程运行时,数据在磁盘和内存之间来回移动。内存管理硬件负责把虚拟地址翻译为物理地址,并让一个进程始终运行于系统的真正内存中,应用程序员只看到虚拟地址,并不知道自己的进程在磁盘与内存之间来回切换。

  从潜在的可能性上说,与进程有关的所有内存都将被系统所使用,如果该进程可能不会马上运行(可能它的优先级低,也可能是它处于睡眠状态),操作系统可以暂时取回所有分配给它的物理内存资源,将该进程的所有相关信息都备份到磁盘上。

  进程只能操作位于物理内存中的页面。当进程引用一个不在物理内存中的页面时,MMU就会产生一个页错误。内存对此事做出响应,并判断该引用是否有效。如果无效,内核向进程发出一个“segmentation violation(段违规)”的信号,内核从磁盘取回该页,换入内存中,一旦页面进入内存,进程便被解锁,可以重新运行——进程本身并不知道它曾经因为页面换入事件等待了一会。

  三、内存的使用

  对于程序员,我们最重要的是能理解不同进程间私有内存空间的含义。C和C++的编译器把私有内存分为3块:基栈、浮动栈和堆。如下图:

clip_image002

  (1)基栈:也叫静态存储区,这是编译器在编译期间就已经固定下来必须要使用的内存,如程序的代码段、静态变量、全局变量、const常量等。

  (2)浮动栈:很多书上称为“栈”,就是程序开始运行,随着函数、对象的一段执行,函数内部变量、对象的内部成员变量开始动态占用内存,浮动栈一般都有生命周期,函数结束或者对象析构,其对应的浮动栈空间的就拆除了,这部分内容总是变来变去,内存占用也不是固定,因此叫浮动栈。

  (3)堆:C和C++语言都支持动态内存申请,即程序运行期可以自由申请内存,这部分内存就是在堆空间申请的。堆位于2GB的最顶端,自上向下分配,这是避免和浮动栈混到一起,不好管理。我们用到malloc和new都是从堆空间申请的内存,new比malloc多了对象的支持,可以自动调用构造函数。另外,new创建对象,其成员变量位于堆里面。

  我们来看一个例子:

const int n = 100;
void Func(void)
{
    char ch = 0;
    char* pBuff = (char*)malloc(10);
    //…
}

  这个函数如果运行,其中n由于是全局静态变量,位于基栈,ch和pBuff这两个函数内部变量,ch位于浮动栈,而pBuff指向的由malloc分配的内存区,则位于堆栈。

  在内存理解上,最著名的例子就是线程启动时的参数传递。

  函数启动一个线程,很多时候需要向线程传参数,但是线程是异步启动的,即很可能启动函数已经退出了,而线程函数都还没有正式开始运行,因此,绝不能用启动函数的内部变量给线程传参。道理很简单,函数的内部变量在浮动栈,但函数退出时,浮动栈自动拆除,内存空间已经被释放了。当线程启动时,按照给的参数指针去查询变量,实际上是在读一块无效的内存区域,程序会因此而崩溃。

  那怎么办呢?我们应该直接用malloc函数给需要传递的参数分配一块内存区域,将指针传入线程,线程收到后使用,最后线程退出时,free释放。

  我们来看例子:

//这个结构体就是参数表
typedef struct _CListen_ListenAcceptTask_Param_ 
{ 
    Linux_Win_SOCKET m_nSocket; 
    //其他参量… …
}SCListenAcceptTaskParam; 
//习惯性写法,设置结构体后,立即声明结构体的尺寸,为后续malloc提供方便
const ULONG SCListenAcceptTaskParamSize = sizeof(SCListenAcceptTaskParam); 
//这里接收到连接请求,申请参数区域,将关键信息带入参数区域,帮助后续线程工作。
bool CListen::ListenTaskCallback(void* pCallParam,int& nStatus) 
{ 
    //正常的函数逻辑… …
    //假定s是accept到的socket,需要传入后续线程工作
    //在此准备一块参数区域,从远堆上申请
    SCListenAcceptTaskParam* pParam = (SCListenAcceptTaskParam*) malloc(SCListenAcceptTaskParamSize); 
    //给参数区域赋值
    pParam->m_nSocket = s; 
    //此处启动线程,将pParam传递给线程… …
    //正常的函数逻辑… …
} 
//这是线程函数,负责处理上文accept到的socket 
bool CListen::ListenAcceptTask(void* pCallParam,int& nStatus) 
{ 
    //第一句话就是强制指针类型转换,获得外界传入的参数区域
    SCListenAcceptTaskParam* pParam= (SCListenAcceptTaskParam*)pCallParam; 
    //正常的函数逻辑… …
    //退出前,必须要做的工作,确保资源不被泄露
    close(pParam->m_nSocket); //关闭socket 
    free(pCallParam); // free传入的参数区域
    //… … 

}

  四、内存bug

  无规则的滥用内存和指针会导致大量的bug,程序员应该对内存的使用保持高度的敏感性和警惕性,谨慎地使用内存资源。

  使用内存时最容易出现的bug是:

  (1)坏指针值错误:在指针赋值之前就用它来引用内存,或者向库函数传送一个坏指针,第三种可能导致坏指针的原因是对指针进行释放之后再访问它的内容。可以修改free语句,在指针释放之后再将它置为空值。

free(p); p = NULL;

  这样,如果在指针释放之后继续使用该指针,至少程序能在终止之前进行信息转储。

  (2)改写(overwrite)错误:越过数组边界写入数据,在动态分配的内存两端之外写入数据,或改写一些堆管理数据结构(在动态分配内存之前的区域写入数据就很容易发生这种情况)

p = malloc(256); p[-1] = 0; p[256] = 0;

  (3)指针释放引起的错误:释放同一个内存块两次,或释放一块未曾使用malloc分配的内存,或释放仍在使用中的内存,或释放一个无效的指针。一个极为常见的与释放内存有关的错误就是在 for(p=start;p=p->next) 这样的循环中迭代一个链表,并在循环体内使用 free(p) 语句。这样,在下一次循环迭代时,程序就会对已经释放的指针进行解除引用操作,从而导致不可预料的结果。

  我们可以这样迭代:

struct node *p, *tart, *temp;
for(p = start; p ; p = temp)
{
    temp = p->next;
    free(p);
}

  总结:这些知识都是本人最近看书总结出来的,可能有很多是个人主观,欢迎拍砖…

Neo4j 初探 —— 图数据库的概念与架构 Neo4j 作为一种强大的图数据库,凭借其独特的图数据模型和高效的数据查询性能,在处理复杂关联数据方面具有显著优势。通过本文的介绍,读者对 Neo4j 的概念、架构、安装配置、应用场景以及注意事项等方面有了全面的了解。从图数据库的诞生背景到与传统数据库的区别,从 Neo4j 的核心概念到详细的架构组成,再到如何在不同操作系统下进行安装配置,以及丰富的应用场景和需要注意的问题,本文为读者呈现了一个系统化的 Neo4j 入门指南。 阅读详情

相关推荐

避坑指南:PCIe设备兼容性那些坑——聊聊MPS/MRRS设置不当引发的血泪史

本文深入探讨了PCIe设备兼容性问题,特别是MPS/MRRS参数设置不当引发的常见故障。通过详细解析MPS(Max Payload Size)和MRRS(Max Read Request Size)的作用机制,提供Linux内核五大配置策略的对比分析,并分享FPGA加速卡等实战案例的排查经验。文章还介绍了诊断工具链、动态调试技巧以及性能优化方法,帮助工程师有效解决PCIe兼容性难题。

weixin_30872499的博客 419

程序员对内存的理解

作者: it笨笨  来源: 博客园  发布时间: 2012-12-13 17:44  阅读: 1466 次  推荐: 9   原文链接   [收藏]     在C和C++语言开发中,指针、内存一直是学习的重点。因为C语言作为一种偏底层的中低级语言,提供了大量的内存直接操作的方法,这一方面使程序的灵活度最大化,同时也为bug埋下很多隐患。   因此,无论如何,我们都要对内存有一个清晰

bodogbo11的专栏 661

Bentley二次开发教程28-交互窗口-案例实战2-EC属性赋值工具

该工具会根据用户输入的路径获取Schema文件的路径,然后通过路径读取对应的Schema文件并在树状图中显示EC类,当用户选择树状图上的节点时,此时会触发事件,根据EC属性添加用户自定义控件用于显示EC属性并可对其进行赋值操作。完成后选取元素,点击界面上的应用,此时元素会被赋予指定EC类,同时修改的EC属性值也会被同步赋予。该工具涉及到的WinForm控件有:TextBox,Button,TreeView,Panel,UserControl(用户自定义控件)。

不见不散的博客 1474

c/c++实现linux下各个内存统计数据获取

c/c++实现linux下各个内存统计数据获取,linux各个内存数据信息可通过/proc/meminfo文件句柄进行访问获取,本文实现就是打开“cat /proc/meminfo”命令管道文件句柄,识别该文件内容格式及字段描述,从中读取到需要的数据信息

技术需要分享 1921

STM32F103VET6实战:用W25Q64外部Flash实现Bootloader远程升级(含完整代码解析)

本文详细介绍了基于STM32F103VET6与W25Q64外部Flash的Bootloader远程升级实现方案,包含硬件选型、存储分区策略、双校验机制及完整代码解析。通过SPI接口实现固件存储与升级,适用于物联网设备开发,提升OTA功能可靠性。

weixin_42620340的博客 357

山东专升本计算机网络基础知识点 --- 计算机网络基础

计算机网络是指将一群具有独立\textcolor{WildStrawberry}{独立}独立功能的计算机通过通信设备及传输媒体等互联起来,在通信软件的支持下,实现计算机间资源共享、信息交换或协同工作\textcolor{WildStrawberry}{资源共享、信息交换或协同工作}资源共享、信息交换或协同工作的系统。计算机网络是计算机技术和通信技术紧密结合的产物\textcolor{WildStrawberry}{计算机网络是计算机技术和通信技术紧密结合的产物}

z339521的博客 2814

内存管理(持续更新中。。。)

单道程序设计系统中,内存被划分成两部分:一部分供操作系统使用(驻留监控程序、内核),一部分供当前正在执行的程序使用。多道程序设计系统中,必须在内存中进一步细分出用户部分,以满足多格进程的要求。细分的任务由操作系统动态完成,这称为内存管理。 一、内零头和外零头: 固定分区:系统生成阶段,内存被分成许多静态分区。进程装到大于等于自身大小的分区中。 动态分区:分区自动创建。每个进程可以

yxy 1226

【LAMMPS学习】四、运行 LAMMPS(2)命令行选项

本部分解释了在安装可执行文件或下载源代码并构建可执行文件后如何运行 LAMMPS。命令文档页面描述了输入脚本的结构以及它们可以包含的命令。

荷塘阅色 5242

内存--通俗理解

什么是内存(一):存储器层次结构 转自:https://www.cnblogs.com/yaoxiaowen/p/7805661.html 首先给大家讲个段子: 2015年开网吧,买了 DDR4 8g 内存条400多根,一根180块,今年2017年,网吧赔了20多万,昨天我把网吧电脑全卖了。内存条600一根,居然赚回了我网吧的钱,感谢三星,感谢人民,感谢党。。。 今年以来,内存条价格暴涨,已经跃升为新的新一代理财产品,所以今天就和大家讨论一下内存的话题,主要内容就是在程序运行过程中,内存的作用以

youhuakongzhi的博客 5090

Android 11.0 app添加校验锁(输入密码才能进入app)

11.0定制化开发中客户要求给app添加锁,就是点击app 图标时,会弹出Dialog,需要输入密码才能进入app中,就是应用校验锁, 最开始想到在Launcher3中实现,但是如果更换了默认Launcher 又不行了 所以最终还是得拦截app启动Activity 从这里入手了 Launcher与APP是在两个不同的进程中,他们之间的通信是通过Binder完成的,点击Launcher上的某个APP,这时会调用Launcher的startActivitySafely方法。 public boolean sta

安卓兼职framework和app工程师的博客 1952

【Python机器学习】决策树与随机森林:解释性与鲁棒性的平衡

本文深入探讨了决策树和随机森林在解释性与鲁棒性之间的权衡。决策树以其完美的可解释性、快速的推理速度和无需特征标准化等优势,在许多场景中仍然是首选算法。一个经过合理剪枝的决策树,其每个决策路径都可以转化为业务规则,这在金融风控、医疗诊断等对透明度有严格要求的领域无可替代。然而,单棵决策树的高方差和容易过拟合的特性限制了其泛化能力。随机森林通过集成学习的思想,巧妙地解决了这个矛盾。它维持了相对较好的解释性(通过特征重要性、OOB估计等方式),同时通过多棵树的投票或平均,大幅降低了模型的方差。

nmdbbzcl的博客 626

1024程序员节特辑 | C++入门指南:内存管理(建议收藏!!)

一、C/C++内存分布1.1 相关例题 二、 C语言中动态内存管理方式:malloc/calloc/realloc/free 2.1 相关面试题 三、C++内存管理方式 3.1 new/delete操作内置类型 3.2 new和delete操作自定义类型 四、operator new与operator delete函数 4.1 operator new抛异常演示 五、new和delete的实现原理 5.1 内置类型 5.2 自定义类型 5.3 相关例题 六、定位new表达式(placement-new)

Zhenyu_Coder的博客 3811

【定位教程2----旋转中心标定之方法一】

【定位教程2----旋转中心标定之方法一】

Quintin 3万+

数据库:一文掌握 Neo4J 的各种指令(Neo4J指令备忘)

Neo4j是一个图形数据库,由节点通过关系连接在一起。如果您有一个高度相互连接的数据集或者有很多连接的查询,您可能会考虑使用图数据库。

数据知道的博客 1万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

使用Neo4j构建企业级别的数据仓库

1.背景介绍 数据仓库是企业在现代数字时代中非常重要的技术基础设施之一。随着数据的规模不断扩大,传统的关系型数据库已经无法满足企业对数据处理和分析的需求。因此,企业需要寻找更高效、更灵活的数据仓库解决方案。Neo4j是一种基于图的数据库管理系统,它可以帮助企业构建高性能、可扩展的数据仓库。在本文中,我们将讨论如何使用Neo4j构建企业级别的数据仓库,以及其核心概念、算法原理、代码实例等方面的内容...

AI天才研究院 1187

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Neo4j实战:5分钟搞定知识图谱节点与关系的增删改查(附完整代码)

本文详细介绍了如何使用Neo4j图数据库快速实现知识图谱中节点与关系的增删改查操作。通过完整的代码示例,帮助开发者掌握创建、查询、更新和删除节点与关系的核心技巧,提升知识图谱构建效率,适用于金融、医疗、电商等多个领域。

i0j1k2l3m的博客 316

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

图数据库之Neo4j

Neo4j 是一种领先的开源图数据库,专门用于处理高度连接的数据结构。它使用图形模型来表示和存储数据,使得它在处理复杂关系和查询时表现出色。以下是对 Neo4j 的详细介绍

youziguo的专栏 1943

探索Neo4j APOC:超高效图数据库操作工具

[Neo4j](https://neo4j.com/) 是一款强大的图形数据库,而 [APOC (Awesome Procedures On Cypher)](https://github.com/neo4j-contrib/neo4j-apoc-procedures) 是 Neo4j 社区贡献的一个重要扩展库,它极大地丰富了Cypher查询语言的功能,使得开发者能够以更加便捷和高效的方式处理复杂

gitblog_00020的博客 868

Node.js Neo4j驱动库实战指南

Node.js Neo4j驱动库实战指南 项目介绍 本教程将深入介绍Node.js Neo4j驱动,这是一个专为Node.js环境设计的Neo4j数据库驱动。它允许开发者高效地与Neo4j图形数据库交互,利用JavaScript的简洁性构建强大的数据关系图谱应用。此驱动支持Neo4j的所有现代特性,包括事务处理、Cypher查询语言以及灵活的数据模型。 项目快速启动 安装驱动 首先,确保你的环境中...

gitblog_00035的博客 611

探索Neo4j Browser:图形数据库的交互式探索利器

是一个直观且功能丰富的Web应用,用于交互式地浏览、查询和管理你的 Neo4j 数据库。 ## **项目简介** Neo4j Browser 是 Neo4j 的官方图形界面工具,它提供了一个现代且用户友好的环境,用于操作和可视化图数据。这款浏览器不仅支持基本的数据查询,还包含了丰富的调试和数据分析工具,帮助开发者和数据分析师以更直观的方式理解复杂关系。 ## **技术分析** ### **

gitblog_00068的博客 1380

【Docker-Neo4j数据卷备份全攻略】:掌握高效备份策略,避免数据丢失危机

掌握Docker-Neo4j的数据卷备份方法,有效防止数据丢失。涵盖容器化环境下数据库持久化存储、定期快照与恢复实操,适用于生产环境运维。详解数据卷导出、压缩与异地保存策略,保障数据安全高效。【Docker-Neo4j 的数据卷备份】完整方案值得收藏

DevPath的博客 340

【AI】Neo4j图数据库

摘要: Neo4j是一款基于图结构的数据库,通过节点和关系直接映射实体间的连接,适用于社交网络、推荐系统等场景。安装时需先配置JDK17/21环境,然后解压Neo4j社区版并设置系统变量,通过命令行启动服务后访问Web客户端(默认地址localhost:7474)。其专用查询语言Cypher支持声明式语法,核心元素包括节点(带标签/属性)、关系(有类型/属性)和路径(节点与关系的组合)。基础操作涵盖节点/关系的创建(CREATE)、查询(MATCH)、修改(SET/REMOVE)和删除(DELETE),例如

399

Spark NEO Core实战:打通Spark与Neo4j的图计算桥梁

在大数据处理领域,Apache Spark凭借其强大的分布式计算能力,已成为批处理和流式计算的行业标准。然而,当业务场景涉及复杂的关联分析、路径查询或社区发现时,传统的表结构计算模型往往难以高效处理深层关系数据。图计算模型通过顶点和边的抽象,成为处理这类关系数据的核心技术。为了在Spark生态中集成图计算能力,Spark NEO Core作为连接Spark与图数据库(如Neo4j)的关键桥梁应运而生。它本质上是一个Spark数据源插件,实现了双向数据通道和计算下推,允许开发者直接在Spark DataFra

weixin_33724570的博客 1016

每天只需2分钟,轻松实现Neo4j数据卷定时备份,你还不知道?

每天2分钟轻松搞定Docker-Neo4j的数据卷备份,避免数据丢失风险。适用于容器化部署的Neo4j数据库,通过定时脚本自动复制数据卷,保障系统稳定与数据安全。操作简单、高效可靠,值得收藏。

AlgoInk的博客 840

MCP + Neo4j:开启知识图谱构建新时代

本文介绍了一种无需编程即可构建知识图谱的创新方法——MCP+Neo4j组合方案。该方案打破传统知识图谱构建的技术壁垒,通过AI助手与图数据库的协同工作,让用户仅需自然语言交互就能完成知识图谱的创建与管理。文章详细阐述了该方法的实施步骤、独特优势及注意事项,指出其具有易用性高、构建速度快、可视化直观等特点,同时提醒需要注意复杂查询优化和安全性等问题。这种方法显著降低了知识图谱应用门槛,为非技术人员参与知识管理提供了新途径。

分享平时的学习心得和笔记 626

别再死记硬背Cypher语法了!用这个电商用户购买图谱实战,5分钟搞定Neo4j增删改查

本文通过电商用户购买图谱实战,详细讲解如何使用Neo4j和Cypher语法进行增删改查操作。从创建用户与商品节点到建立购买关系,再到复杂查询和性能优化,帮助开发者快速掌握知识图谱构建技巧,提升数据分析效率。

weixin_30315723的博客 285
上一篇: nginx 配置
下一篇: cmake 概述
dodo_check
博客等级 码龄19年 29粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值