CTF-PWN-堆-【malloc和free的工作流程】

文章目录

  • 关于ptmalloc的思考
    • 缓存思想
  • chunk结构
  • large bin补充
  • fast bin 补充
  • unsorted bin 补充
  • top chunk 补充
  • mmaped chunk补充
  • Last remainder补充
    • last remainder的产生
  • malloc_state补充
  • mmap收缩阈值
  • mmap分配阈值
  • ptmalloc响应用户内存分配要求工作流程
  • free时工作流程

大佬的关于ptmalloc的知识分享的链接

以下都是基于glibc-2.19版本,其他版本会有变动,但依然可提供参考

关于ptmalloc的思考

缓存思想

理解缓存思想其实就是一种提高效率的思想

  1. 请求分配内存时,系统调用 brk() 分配一块比较大的内存作为缓存, 之后即使没有在 Bins 中也找不到, 也不需要每次触发系统调用, 直接切割这块大的内存即可.
    缓存的思想,如果没有缓存,那么这将使得每次内存分配都系统调用,速度效率低下

  2. 释放内存时暂时不还给系统,标记空闲,等下一次需要相同大小,直接使用该块空闲内存即可,从而减少系统调用

  3. 除了以上两种缓存,Fastbin也是一种缓存手段,对于长度在fastbin范围内的chunk释放后不会放到Bins中,也不会标记为空闲(没有标记为空闲即成功避免合并),下次分配内存时首先查找Fastbins,这就避免了切割

  4. 而unsorted bin属于刚刚释放的内存与bins之间的缓存。刚刚释放的内存会先放到 Unsorted 缓存, 在下一次内存分配时, 会优先于 Bins 查找, 如果能命中 Unsorted 缓冲最好, 否则就把 Unsorted 中的 chunk 统一整理到对应 Bins.

  5. last_remainder也是一种缓存,是切割时剩下的那个,下次切割也从它开始。 大致就是希望一直切割同一个 chunk. 在遍历 Unsorted 时使用, 但是它的使用是有条件的.

chunk结构

在这里插入图片描述

large bin补充

对于 large bins, 分割边界是递增的, 举个简单例子: 前 32 个 large bins 的分割边界都是 64 bytes, 之后 16 个 large bins 的分割边界是 512 bytes. 以上仅为字长为 32 位的情况下

 32 bins of size      6416 bins of size     5128 bins of size    40964 bins of size   327682 bins of size  2621441 bin  of size what's left

large bin 有些特殊, 空闲 chunk 的存放需要排序, large_bin->bk 为最小 size 的 chunk, large_bin->fd 为最大 size 的 chunk.

fast bin 补充

当进行内存分配时先从 Fastbins 中进行查找, 之后才在 Bins 进行查找; 释放内存时, 当chunk size < max_fast 会先存放到 Fastbins.
Fastbins 的合并(清空), 也就是 malloc_consolidate 这个函数的工作.

  • 何时会触发 malloc_consolidate(仅对 _int_malloc 函数而言) ?
  1. small bins 尚未初始化
  2. 需要 size 大于 small bins
  • malloc_consolidate 如何进行合并 ?
    遍历 Fastbins 中的 chunk, 设置每个 chunk 的空闲标志位为 0, 并合并相邻的空闲 chunk, 之后把该 chunk 存放到 unsorted bin 中.
    Fastbins 是单向链表, 可以通过 fastbin->fd 遍历 Fastbins.

TRIM_FASTBINS=1 fast bin 会与相邻的 top chunk 进行合并,为0时不会合并

unsorted bin 补充

只有一个 unsorted bin, 进行内存分配查找时先在 Fastbins, small bins 中查找, 之后会在 unsorted bin 中进行查找, 并整理 unsorted bin 中所有的 chunk 到 Bins 中对应的 Bin. unsorted bin 位于 bin[1].
unsorted_bin->fd 指向双向环链表的头结点, unsorted_bin->bk 指向双向环链表的尾节点, 在头部插入新的节点

top chunk 补充

对于非主分配区会预先从 mmap 区域分配一块较大的空闲内存模拟 sub-heap,通过管 理 sub-heap 来响应用户的需求,因为内存是按地址从低向高进行分配的,在空闲内存的最 高处,必然存在着一块空闲 chunk,叫做 top chunk.
当 bins 和 fast bins 都不能满足分配需 要的时候,ptmalloc 会设法在 top chunk 中分出一块内存给用户,如果 top chunk 本身不够大, 分配程序会重新分配一个 sub-heap,并将 top chunk 迁移到新的 sub-heap 上, 新的 sub-heap 与已有的 sub-heap 用单向链表连接起来,然后在新的 top chunk 上分配所需的内存以满足分配的需要,
实际上,top chunk 在分配时总是在 fast bins 和 bins 之后被考虑,所以,不论 top chunk 有多大,它都不会被放到 fast bins 或者是 bins 中.
top chunk 的大小是随着分配和回收不停变换的,如果从 top chunk 分配内存会导致 top chunk 减小,如果回收的 chunk 恰好 与 top chunk 相邻,那么这两个 chunk 就会合并成新的 top chunk,从而使 top chunk 变大.
如果在 free 时回收的内存大于某个阈值,并且 top chunk 的大小也超过了收缩阈值,ptmalloc 会收缩 sub-heap,如果 top-chunk 包含了整个 sub-heap,ptmalloc 会调用 munmap 把整个 sub-heap 的内存返回给操作系统.
由于主分配区是唯一能够映射进程 heap 区域的分配区,它可以通过 sbrk()来增大或是 收缩进程 heap 的大小,ptmalloc 在开始时会预先分配一块较大的空闲内存 (也就是所谓的 heap), 主分配区的 top chunk 在第一次调用 mallocd 时会分配一块(chunk_size + 128KB) align 4KB 大小的空间作为初始的 heap,
用户从 top chunk 分配内存时,可以直接取出一块内存给用户.在回收内存时,回收的内存恰好与 top chunk 相邻则合并成新的 top chunk,
当该次回收的空闲内存大小达到某个阈值,并且 top chunk 的大小也超过了收缩阈值,会执行内存收缩,减小 top chunk 的大小,但至少要保留一个页大小的空闲内存,从而把内存归还给 操作系统.
如果向主分配区的 top chunk 申请内存,而 top chunk 中没有空闲内存, ptmalloc 会调用 sbrk()将的进程 heap 的边界 brk 上移, 然后修改 top chunk 的大小.

mmaped chunk补充

当需要分配的 chunk 足够大,而且 fast bins 和 bins 都不能满足要求,甚至 top chunk 本 身也不能满足分配需求时,ptmalloc 会使用 mmap 来直接使用内存映射来将页映射到进程空 间.
这样分配的 chunk 在被 free 时将直接解除映射, 于是就将内存归还给了操作系统,再次对这样的内存区的引用将导致 segmentation fault 错误.这样的 chunk 也不会包含在任何 bin 中.

Last remainder补充

Last remainder 是另外一种特殊的 chunk,就像 top chunk 和 mmaped chunk 一样,不会在任何 bins 中找到这种 chunk.当需要分配一个 small chunk, 但在 small bins 中找不到合适 的 chunk, 如果 last remainder chunk 的大小大于所需的 small chunk 大小,last remainder chunk 被分裂成两个 chunk, 其中一个 chunk 返回给用户, 另一个 chunk 变成新的 last remainder chuk.

last remainder的产生

bins链(fast bin除外)存在free chunk时,若malloc的请求大小小于free chunk,就会切割这个free chunk,剩余的chunk就是last remainder,last remainder会被放入unsorted bin中

产生last remainder后,malloc_state结构体中的last_remainder成员指针会被初始化,指向这个last_remainder

  • 切割unsorted bin
    当unsorted bin有free chunk可以给malloc切割使用时:
  1. 将free chunk放置到对应大小的bins链
  2. 切割free chunk,产生last remainder
  3. last remainder放入unsorted bin
  • 切割small bin、large bin
  1. 切割free chunk,产生last remainder
  2. last remainder放入unsorted bin

malloc_state补充

只存在一个主分区, 但是允许多个非主分区, 主分配区域可以访问 heap 区域 和 mmap 区域, 非主分区只能访问 mmap 区域, 每次用 mmap 分配一块大小的内存当做 sub-heap, 用于模拟 heap.

mmap收缩阈值

M_TRIM_THRESHOLD用于设置mmap收缩阈值,默认值为128KB。自动收缩只会在free时才发生,如果当前free的chunk大小加上前后能合并chunk的大小大于64KB,并且top chunk的大小达到mmap收缩阈值,对于主分配区,调用malloc_trim()返回一部分内存给操作系统,对于非主分配区,调用heap_trim()返回一部分内存给操作系统,在发生内存收缩时,还是从新设置mmap分配阈值和mmap收缩阈值。

mmap分配阈值

M_MMAP_THRESHOLD用于设置mmap分配阈值,默认值为128KB,ptmalloc默认开启动态调整mmap分配阈值和mmap收缩阈值。

当用户需要分配的内存大于mmap分配阈值,ptmalloc的malloc()函数其实相当于mmap()的简单封装,free函数相当于munmap()的简单封装。相当于直接通过系统调用分配内存,回收的内存就直接返回给操作系统了。因为这些大块内存不能被ptmalloc缓存管理,不能重用,所以ptmalloc也只有在万不得已的情况下才使用该方式分配内存。

ptmalloc响应用户内存分配要求工作流程

  1. 获取分配区的锁, 为了防止多个线程同时访问同一个分配区, 在进行分配之前需要取得分配区域的锁. 线程先查看线程私有实例中是否已经存在一个分配区, 如果存 在尝试对该分配区加锁, 如果加锁成功, 使用该分配区分配内存, 否则, 该线程搜 索分配区循环链表试图获得一个空闲(没有加锁)的分配区. 如果所有的分配区都 已经加锁, 那么 ptmalloc 会开辟一个新的分配区, 把该分配区加入到全局分配区循 环链表和线程的私有实例中并加锁, 然后使用该分配区进行分配操作. 开辟出来的 新分配区一定为非主分配区, 因为主分配区是从父进程那里继承来的. 开辟非主分配区时会调用 mmap()创建一个 sub-heap, 并设置好 top chunk.

  2. 将用户的请求大小转换为实际需要分配的 chunk 空间大小. 具体查看 request2size 宏 (malloc.c:3332)

  3. 判断所需分配 chunk 的大小是否满足 chunk_size <= max_fast (max_fast 默认为 64B), 如果是的话, 则转下一步, 否则跳到第 5 步. (malloc.c:3340)

  4. 首先尝试在 Fastbins 中查找所需大小的 chunk 分配给用户. 如果可以找到, 则分配结束. 否则转到下一步. (malloc.c:3340)

  5. 判断所需大小是否处在 small bins 中, 即判断 chunk_size < 512B 是否成立. 如果 chunk 大小处在 small bins 中, 则转下一步, 否则转到第 7 步. (malloc.c:3377)

  6. 根据所需分配的 chunk 的大小, 找到具体所在的某个 small bin, 从该 Bin 的尾部摘取一个恰好满足大小的 chunk. 若成功, 则分配结束, 否则, 转到 8. (malloc.c:3377)

  7. 到了这一步, 说明需要分配的是一块大的内存, 于是, ptmalloc 首先会遍历 Fastbins 中的 chunk, 将相邻的空闲 chunk 进行合并, 并链接到 unsorted bin 中. 对于 Fastbins 的合并是由 malloc_consolidate 做处理. (malloc.c:3421)

  8. 后序遍历unsort bin,如果存在大小正好合适的chunk,那么便直接拿去使用,结束循环遍历。(后面的就不管了,保持原样
    如果大小不是正好,那么便放到相应的bin中去,如果是small bin就放到small bin,是large bin就放到large bin(fast bin被包含在small bin里面了
    遍历所有chunk遍历完之后,由于没有一个大小正好的chunk,那么便到刚刚所分配到不同bin中去寻找,如果size是属于small bin的,那么便到small bin中去寻找,如果有比需要的size更大的chunk存在的话,那么就切割,切割剩的一部分如果不小于0x10的话就放到unsort bin中去,如果小于就一起给了。如果small bin当中没有比需要size更大的chunk存在,那么就往large bin中去寻找了(就是在small bin中切割的情况。
    在large bin里后序遍历(bk指针开始)。如果找到了比需要size大的chunk,那么也同样切割,切割剩下的一部分不小于0x10则放到unsort bin中去,小于则一起给了。
    如果还是没有找到,则到下一步

  9. 到了这一步说明在对应的 bin 上没有找到合适的大小, 无论是 small bin 还是 large bin, 对于 small bin, 如果没有对应大小的 small bin, 只能 idx+1. 对于 large bin,在上一步的 large bin 并不一定能找到合适的 chunk 进行切割, 因为 large bins 间隔是很大的, 假如当前的 idx 的 large bin 只有一个 chunk, 但是所需 size 大于该 chunk, 这就导致找不到合适的, 只能继续 idx+1, 最后都需要根据 bitmap 找到之后第一个非空闲的 bin. 在这两种情况下找到的 bin 中的 chunk 一定可以进行切割或者全部分配(剩余的 size < MINSIZE) (malloc.c:3649)

  10. 如果仍然都没有找到合适的 chunk, 那么就需要操作 top chunk 来进行分配了. 判断 top chunk 大小是否满足所需 chunk 的大小, 如果是, 则从 top chunk 中分出一块来. 否则转到下一步. (malloc.c:3749)

  11. 到了这一步, 说明 top chunk 也不能满足分配要求, 所以, 于是就有了两个选择: 如果是主分配区, 判断是否为第一次调用 ,如果是则需要进行一次初始化工作, 分配一块大小为(chunk_size + 128KB) align 4KB 大小的空间作为初始的 heap.若已经初始化过了,则调用 sbrk(), 增加 top chunk 大小,然后top chunk 中切割出一个 chunk。 top chunk 中切割出一个 chunk, 使之满足分配需求, 并将内存指针返回给用户。如果是非主分配区,则判断所需分配的 chunk 大小是否大于等于 mmap 分配阈值 。 如果是的话,则到下一步,否则调用 mmap 来分配一个新的 sub-heap, 增加 top chunk 大小,然后在 top chunk 中切割出一个 chunk, 使之满足分配需求, 并将内存指针返回给用户. 在这里, 需要依靠 chunk 的大小来决定到底使用哪种方法.

  12. 使用 mmap()来直接分配,用 mmap 系统调用为程序的内存空间映射一块 chunk_size align 4kB 大小的空间. 然后将内存指针返回给用户.

free时工作流程

  1. free()函数同样首先需要获取分配区的锁, 来保证线程安全.

  2. 判断传入的指针是否为 0, 如果为 0, 则什么都不做, 直接 return.否则转下一步.

  3. 判断 chunk 的大小和所处的位置, 若 chunk_size <= max_fast, 并且 chunk 并不位于 heap 的顶部, 也就是说并不与 Top chunk 相邻, 则转到下一步, 否则跳到第 5 步.(因为与 top chunk 相邻的 chunk(fastbin) ,会与 top chunk 进行合并, 所以这里不仅需要判断大小, 还需要判断相邻情况)

  4. 将 chunk 放到 Fastbins 中, chunk 放入到 Fastbins 中时, 并不修改该 chunk 使用状 态位 P.也不与相邻的 chunk 进行合并.只是放进去, 如此而已.这一步做完之后 释放便结束了, 程序从 free()函数中返回.

  5. 判断所需释放的 chunk 是否为 mmaped chunk, 如果是, 则调用 munmap()释放 mmaped chunk, 解除内存空间映射, 该该空间不再有效.如果不是mappedchunk并且开启了 mmap 分配阈值的动态调整机制, 并且当前回收的 chunk 大小大于 mmap 分配阈值, 则将 mmap 分配阈值设置为该 chunk 的大小, 将 mmap 收缩阈值设定为 mmap 分配阈值的 2 倍, 释放完成, 否则跳到下一步.

  6. 判断前一个 chunk 是否处在使用中, 如果前一个块也是空闲块, 则合并.并转下一步.

  7. 判断当前释放 chunk 的下一个块是否为 top chunk, 如果是, 则转第 9 步, 否则转 下一步.

  8. 判断下一个 chunk 是否处在使用中, 如果下一个 chunk 也是空闲的, 则合并, 并将合并后的 chunk 放到 unsorted bin 中.注意, 这里在合并的过程中, 要更新 chunk 的大小, 以反映合并后的 chunk 的大小.并转到第 10 步.

  9. 如果执行到这一步, 说明释放了一个与 top chunk 相邻的 chunk.则无论它有多大, 都将它与 top chunk 合并, 并更新 top chunk 的大小等信息.转下一步. (malloc.c:3950)

  10. 判断合并后的 chunk 的大小是否大于 FASTBIN_CONSOLIDATION_THRESHOLD(默认 64KB), 如果是的话, 则会触发进行 Fastbins 的合并操作(malloc_consolidate), Fastbins 中的 chunk 将被遍历, 并与相邻的空闲 chunk 进行合并, 合并后的 chunk 会被放到 unsorted bin 中. Fastbins 将变为空, 操作完成之后转下一步.

  11. 判断 top chunk 的大小是否大于 mmap 收缩阈值(默认为 128KB), 如果是的话, 对于主分配区, 则会试图归还 top chunk 中的一部分给操作系统.但是最先分配的 128KB 空间是不会归还的, ptmalloc 会一直管理这部分内存, 用于响应用户的分配 请求;如果为非主分配区, 会进行 sub-heap 收缩, 将 top chunk 的一部分返回给操 作系统, 如果 top chunk 为整个 sub-heap, 会把整个 sub-heap 还回给操作系统.做 完这一步之后, 释放结束, 从 free() 函数退出.可以看出, 收缩堆的条件是当前 free 的 chunk 大小加上前后能合并 chunk 的大小大于 64k, 并且要 top chunk 的大 小要达到 mmap 收缩阈值, 才有可能收缩堆.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/193292.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Delphi】实现彩色日志显示框

目录 一、前言 二、实现方法 1. 第一步 2. 第二步 3. 第三步 三、主程序代码 四、下载 1. 可执行程序 2. 程序源代码 一、前言 在用Delphi做日常开发的时候&#xff0c;经常需要显示程序运行的日志&#xff0c;一般我们会使用TMemo&#xff0c;使用起来简单&#xff0c…

ElementPlus中 使用ElLoading.service, spinner: ‘el-icon-loading‘不生效

let downloadLoadingInstance ElLoading.service({ text: "正在下载数据&#xff0c;请稍候",spinner: el-icon-loading, background: "rgba(0, 0, 0, 0.7)", })使用以上代码时&#xff0c;加载的圆圈出不来&#xff0c;使用f12查看&#xff0c;即使能出…

BEVFormer环境配置

官网的教程说是Step By Step&#xff0c;但是实际上我按照步骤安装下来运行不了&#xff08;BEVFormer GitHub地址&#xff09;。主要是安装后关于包依赖产生的某些错误&#xff0c;特别是安装nuscenes-devkit没有在步骤中列出来&#xff0c;后面就不好解决某些包的版本依赖了。…

多级缓存自用

1.什么是多级缓存 传统的缓存策略一般是请求到达Tomcat后,先查询Redis,如果未命中则查询数据库,如图: 存在下面的问题: •请求要经过Tomcat处理,Tomcat的性能成为整个系统的瓶颈 •Redis缓存失效时,会对数据库产生冲击 多级缓存就是充分利用请求处理的每个环节,添加缓…

C语言实现猜数字游戏

前面我们已经了解了分支循环、数据类型及变量的知识点&#xff0c;今天我将用之前学过的知识进行实操&#xff0c;将所学的知识进行巩固和提升。下面的讲解仅我个人认知水平&#xff0c;如有欠缺之处&#xff0c;欢迎大家指正&#xff0c;并且我希望初学者在看完讲解后可以独立…

强化学习------时序差分(Temporal-Difference Learning)

简介 时序差分方法&#xff08;Temporal-Difference Learning&#xff09;简称TD算法是强化学习中非常经典的一种方法&#xff0c;Sarsa算法和Q-learning算法都是基于时序差分这种方法的。 强化学习分为基于模型和不基于模型的方法 基于模型的方法&#xff1a;是一种通过建立…

Redis之五大基础数据类型(详细总结 面试必备)

Redis之五大基础数据类型 Redis 共有 5 种基本数据类型&#xff1a;String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、Set&#xff08;集合&#xff09;、Hash&#xff08;散列&#xff09;、Zset&#xff08;有序集合&#xff09;。 这 5 种数据类…

64. 最小路径和(Leetcode)

文章目录 前言一、题目分析二、算法原理1.状态表示2.状态转移方程3.初始化4.填表顺序5.返回值是什么 三、代码实现总结 前言 在本文章中&#xff0c;我们将要详细介绍一下Leetcode6最小路径相关的内容 一、题目分析 二、算法原理 1.状态表示 列出dp表&#xff0c;dp[i][j]代…

IDEA导入JavaWeb项目(Maven)

IDEA导入JavaWeb(Maven)项目教程 运行教程 亲爱的粉丝们&#xff0c;我深知你们对IDEA导入JAVAWeb工程的迫切需求。在这个充满竞争的时代&#xff0c;每一个项目都离不开高效的沟通。过程中需要对应的环境适配和软件安…

操作PDF相关的工具,EPUB转PDF,golang

unipdf 安装依赖 go get github.com/unidoc/unipdf/v3 示例代码 https://github.com/unidoc/unipdf-examples 获取KEY 登录 https://cloud.unidoc.io/ 注册账号&#xff0c;生成 KEY&#xff0c;但是需要收费。 chromedp 使用Golang编写&#xff0c;主要功能是调用浏览器内…

代码随想录算法训练营第四十一天 _ 动态规划_343. 整数拆分、96.不同的二叉搜索树、01背包问题。

学习目标&#xff1a; 动态规划五部曲&#xff1a; ① 确定dp[i]的含义 ② 求递推公式 ③ dp数组如何初始化 ④ 确定遍历顺序 ⑤ 打印递归数组 ---- 调试 引用自代码随想录&#xff01; 60天训练营打卡计划&#xff01; 学习内容&#xff1a; 343. 整数拆分 动态规划五步曲&…

Mysql之数据处理增删改

Mysql之数据处理增删改查 插入数据INSERT INTO语句的使用INSERT 与子查询结合 更新数据(修改数据)UPDATE SET语句 删除数据DELETE FROM语句 Mysql8新特性&#xff1a;计算列 插入数据 INSERT INTO语句的使用 用 INSERT INTO 语句&#xff0c;向表中插入数据 方式一&#xff1a;…

Web漏洞分析-SQL注入XXE注入(上)

随着互联网的不断普及和Web应用的广泛应用&#xff0c;网络安全问题愈发引起广泛关注。在网络安全领域中&#xff0c;SQL注入和XXE注入是两个备受关注的话题&#xff0c;也是导致许多安全漏洞的主要原因之一。本博客将深入研究这两种常见的Web漏洞&#xff0c;带您探寻背后的原…

一个用c#瞎写的sftp工具

0.下载地址 https://wwus.lanzouj.com/iOZUv1gkgpze 密码:123456 1.能进行单个和批量下载, 没有弄上传 2.速度奇差,可能是某些地方没弄好.有一定的进度显示,但是不太准. 3.很多地方没弄好,有能力的自己弄一下 4.在app.config文件配置sftp

深度学习 第3章 Python程序设计语言(3.2 Python程序流程控制)

无论是在机器学习还是深度学习中&#xff0c;Python已经成为主导性的编程语言。而且&#xff0c;现在许多主流的深度学习框架&#xff0c;例如PyTorch、TensorFlow也都是基于Python。本课程主要是围绕“理论实战”同时进行&#xff0c;所以本章将重点介绍深度学习中Python的必备…

Echarts大屏可视化_03 定制柱状图

柱状图模块引入 1.找到合适的图表 在echarts中寻找与目标样式相近的图表 Examples - Apache ECharts 2. 引入柱状图 使用立即执行函数构建&#xff0c;防止变量全局污染 实例化对象 将官网中提供的option复制到代码中&#xff0c;并且构建图表 // 柱状图模块1 (function () {/…

Python爬虫:通过js逆向分析某翻译网站的原理

Python爬虫&#xff1a;通过js逆向分析某翻译网站的原理 1. 网站实现原理2. 抓取接口3. 参考代码和运行结果 1. 网站实现原理 首先&#xff0c;说一下爬取的网站&#xff1a;百度翻译。网站实现翻译的效果是通过接口实现的&#xff0c;也就是各位听到的ajax技术(只需要更换对应…

Sharding-Jdbc(4):Sharding-Jdbc分库

1 新建数据库 创建ds_0数据库和ds_1数据库&#xff0c;在两个数据库新建表如下&#xff1a; CREATE TABLE t_order (order_id bigint(20) NOT NULL,user_id bigint(20) NOT NULL,PRIMARY KEY (order_id) ) ENGINEInnoDB DEFAULT CHARSETutf8 COLLATEutf8_bin; 2 新建maven项目…

QNX时钟调研

SYSPAGE_ENTRY()的使用&#xff0c;SYSPAGE_ENTRY 测试QNX下printf(“poo\n”);的耗时 #include <sys/neutrino.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> #include <sys/syspage.h>int main( void ) {uint64_t cps, …

计算机网络的性能

目录 一、计算机网络的性能指标——宽带 二、计算机网络的性能指标——时延 三、计算机网络的性能指标——时延带宽积 四、计算机网络的性能指标——往返时延 五、计算机网络的性能指标——吞吐量 六、计算机网络的能能指标——利用率 计算机网络的定义&#xff1a;计算机网络时…