js实现常见排序算法

article/2025/11/9 20:29:51

文章目录

  • 前言
  • 一、排序相关概念
    • 1.比较排序和非比较排序
      • 比较排序
      • 非比较排序
    • 2.稳定性和不稳定性
  • 二、各排序算法对比
  • 三、排序算法中的通用函数以及对数器
      • 1.通用函数
        • 交换函数
        • 取两索引的中间下标,中间值mid
      • 2.对数器
  • 四、各排序算法的实现
    • 1.冒泡排序
      • 算法思想
      • 过程图解
      • 代码实现
      • 算法分析
    • 2.选择排序
      • 算法思想
      • 过程图解
      • 代码实现
      • 算法分析
    • 3.插入排序
      • 算法思想
      • 过程图解
      • 代码实现
      • 算法分析
    • 4.希尔排序
      • 算法思想
      • 过程图解
      • 代码实现
      • 算法分析
    • 5.归并排序
      • 算法思想
      • 过程图解
      • 代码实现
      • 算法分析
    • 6.快速排序
      • 算法思想
      • 过程图解
      • 代码实现
      • 算法分析
  • 实际速度对比
  • 引用


前言

排序算法这玩意吧,感觉平时写代码又用的少,然后你不懂又不行,还每次敲完,过一阵子又忘了,就参考了很多大佬的文章记录一下方便以后复习。


一、排序相关概念

1.比较排序和非比较排序

我们将排序的时候元素之间是否需要比较分为:比较排序和非比较排序

比较排序

通过元素之间比较之后再决定先后顺序,如下面的冒泡排序,每次都是选取两个元素进行比较。比较排序的时间复杂度通常为 O(n2) 或者 O(nlogn),时间复杂度不能突破O(nlogn),所以也叫非线性时间比较类排序。

冒泡排序

非比较排序

非比较排序就是不需要通过元素之间的比较就可以确定每个元素的位置,如下是基数排序的动图,排序时每个元素并不需要比较,而是有自己固定的位置。它可以突破比较排序的下限O(nlogn),可以达到 O(n),但是都需要额外的空间开销,所以也称线性时间非比较类排序。

基数排序

2.稳定性和不稳定性

稳定: 如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
不稳定:如果a原本在b的前面,而a=b,排序之后 a 可能会出现在 b 的后面。

二、各排序算法对比

各算法对比

三、排序算法中的通用函数以及对数器

实现各算法之前先实现一些简单的通用函数以及实现一个对数器用于检验我们实现的算法是否正确。

1.通用函数

交换函数

// 普通版本(辅助变量temp,适合所有场景,大家最常用的方法,较慢)
function swap(arr,i,j) {let temp = arr[i];arr[i] = arr[j];arr[j] = temp;
}
// 位运算版本(位运算一般较快.但特殊情况自己与自己交换会变为0)
function swap2(arr,i,j) {arr[i] = arr[i] ^ arr[j];arr[j] = arr[i] ^ arr[j];arr[i] = arr[i] ^ arr[j];
}
// 加减版本(可能越界)
function swap3(arr,i,j) {arr[i] = arr[i] + arr[j];arr[j] = arr[i] - arr[j];arr[i] = arr[i] - arr[j];
}

取两索引的中间下标,中间值mid

// 普通版 有可能越界
let mid = Math.floor((left + right)/2);
// 优化版
let mid = Math.floor(left + (right - left)/2);
// 位运算版
//>>右移,带符号 >>>右移,无符号 右移一位相当于/2
//注意位移运算外面的小括号,因为位运算优先级低
//位运算相对较快
let mid = Math.floor(left + ((right - left) >> 1));

2.对数器

用原生的方法检验自己写的方法是否正确。先随机产生数组,用自己的方法进行排序,再用原生的方法进行排序,比较两次排序是否结果一样。可以调整随机产生的数组的数据量产生更大的数据验证。

class Comparator {constructor() {// 用于后续对比各排序算法时排序同样的随机数据this.dataStore = [];}// 生成随机数组getRandomArr(size, maxValue) {return Array(size).fill(0).map(() => Math.floor(Math.random() * maxValue));}// 比较两个数组是否相等isEqual(arr1, arr2) {if ((arr1 == null && arr2 != null) || (arr1 != null && arr2 == null)) {return false;}if (arr1 == null && arr2 == null) {return true;}if (arr1.length != arr2.length) {return false;}for (let i = 0; i < arr1.length; i++) {if (arr1[i] != arr2[i]) {return false;}}return true;}// 复制数组copyArray(arr) {if (arr == null) {return null;}return [...arr];}// 原生排序sort(arr) {arr.sort((a, b)=>a - b);}setData(size) {this.dataStore = this.getRandomArr(size,100)}// 测试我们写的排序 传入我们要检测的排序函数以及随机数据长度test(sortFn) {// 先获取俩个同样的随机数据的数组let arr1 = this.copyArray(this.dataStore)let arr2 = this.copyArray(this.dataStore);// 先用原生方法对arr1进行排序this.sort(arr1);// 然后用我们自己写的方法进行排序 并且记录一下消耗时间方便后续对各排序进行对比let startTime = new Date().getTime();sortFn(arr2);let endTime = new Date().getTime();let interval = endTime - startTime;// 通过isEqual函数验证我们写的排序是否正确if (this.isEqual(arr1, arr2)) {console.log(`${sortFn.name}排序正确:耗时${interval}毫秒`);} else {console.log(`${sortFn.name}排序错误`);}}
}let comparator = new Comparator; 
comparator.setData(10000);  // 表示生成一个10000组随机数据的数组用于测试
comparator.test(bubbleSort); // bubbleSort排序正确:耗时203毫秒
comparator.test(selectionSort); // selectionSort排序正确:耗时65毫秒
comparator.test(insertSort); // insertSort排序正确:耗时35毫秒
comparator.test(shellSort); // shellSort排序正确:耗时6毫秒

四、各排序算法的实现

有了上面完成的比较器,我们可以很容易检验我们的排序算法是否正确,接下来是各种排序的具体实现

1.冒泡排序

依次比较两个相邻的元素,一层一层的将较大的元素往后移动,其现象和气泡在上升过程中慢慢变大类似,故成为冒泡排序。

算法思想

从第一个和第二个开始比较,如果第一个比第二个大,则交换位置,然后比较第二个和第三个,逐渐往后

经过第一轮后最大的元素已经排在最后,所以重复上述操作的话第二大的则会排在倒数第二的位置。

那重复上述操作n-1次即可完成排序,因为最后一次只有一个元素所以不需要比较

过程图解

冒泡排序

代码实现

function bubbleSort(arr) {// 第一层是循环是遍历的次数for (let i = 0; i < arr.length; i++){// 第二层表示每次遍历都让相邻的两个元素进行对比,大的往后移for (let j = 0; j < arr.length-i-1; j++){if (arr[j] > arr[j + 1]) {swap(arr, j, j + 1);}}}
}comparator.test(bubbleSort);

算法分析

稳定性:我们从代码中可以看出只有前一个元素大于后一个元素才可能交换位置,所以相同元素的相对顺序不可能改变,所以它是稳定排序

比较性:因为排序时元素之间需要比较,所以是比较排序

时间复杂度:因为它需要双层循环n*(n-1)),所以平均时间复杂度为O(n^2)

空间复杂度:只需要常数个辅助单元,所以空间复杂度为O(1),我们把空间复杂度为O(1)的排序成为原地排序(in-place)

2.选择排序

工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,所以称为:选择排序

算法思想

设第一个元素为比较元素,依次和后面的元素比较,比较完所有元素找到最小的元素,将它和第一个元素互换

重复上述操作,我们找出第二小的元素和第二个位置的元素互换,以此类推找出剩余最小元素将它换到前面,即完成排序

过程图解

选择排序

代码实现

function selectionSort(arr) {// 第一层循环是遍历的次数for (let i = 0; i < arr.length; i++){// 第二层表示每次遍历的元素中都能找到最小的并且放到最前面for (let j = i + 1; j < arr.length; j++){if (arr[i] > arr[j]) {swap(arr, i, j);}}}
}
comparator.test(selectionSort);

算法分析

稳定性:因为存在任意位置的两个元素交换,比如[5, 8, 5, 2],第一个5会和2交换位置,所以改变了两个5原来的相对顺序,所以为不稳定排序。
比较性:因为排序时元素之间需要比较,所以是比较排序
时间复杂度:选择排序同样是双层循环n*(n-1)),所以时间复杂度也为:O(n^2)
空间复杂度:只需要常数个辅助单元,所以空间复杂度也为O(1)

3.插入排序

工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

算法思想

第二个元素开始和前面的元素进行比较,如果前面的元素比当前元素大,则将前面元素 后移,当前元素依次往前,直到找到比它小或等于它的元素插入在其后面
然后选择第三个元素,重复上述操作,进行插入
依次选择到最后一个元素,插入后即完成所有排序

过程图解

插入排序

代码实现

function insertSort(arr) {// 第一层循环表示依次从第一个元素开始插入到前面已经维持好的序列中for (let i = 1; i < arr.length; i++){// 使用临时变量存储当前要插入的值let temp = arr[i];// 要插入的元素和前面已经排好序的元素依次对比,直到前面的元素比当前要插入的小,或者前面已经没有可以对比的元素了let j = i-1;for (; j >= 0 && temp < arr[j]; j--){arr[j+1] = arr[j];}arr[j+1] = temp;}}
comparator.test(insertSort);

算法分析

稳定性:从代码我们可以看出只有比较元素大于当前元素,比较元素才会往后移动,所以相同元素是不会改变相对顺序。
比较性:因为排序时元素之间需要比较,所以是比较排序
时间复杂度:插入排序同样需要两次循坏一个一个比较,故时间复杂度也为O(n^2)
空间复杂度:只需要常数个辅助单元,所以空间复杂度也为O(1)

4.希尔排序

第一个突破O(n2)的排序算法,是简单插入排序经过改进之后的一个更高效的版本。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。

算法思想

先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序

过程图解

希尔排序

代码实现

function shellSort(arr) {// 设置增量let step = Math.floor(arr.length / 2);while (step > 0) {// 从增量值开始进行插入排序for (let i = step; i < arr.length; i++) {let temp = arr[i];let j = i - step;for (; j >= 0 && arr[j] > temp; j -= step) {arr[j + step] = arr[j];}arr[j + step] = temp;}// 每次增量缩小一半step = Math.floor(step / 2)}
}comparator.test(shellSort);

算法分析

稳定性:因为希尔排序是间隔的插入,所以存在相同元素相对顺序被打乱,所以是不稳定排序
比较性:因为排序时元素之间需要比较,所以是比较排序
时间复杂度:最坏时间复杂度O(n2)平均复杂度为O(n1.3)
空间复杂度:只需要常数个辅助单元,所以空间复杂度也为O(1)

5.归并排序

归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

算法思想

把长度为n的输入序列分成两个长度为n/2的子序列;
对这两个子序列分别采用归并排序;
将两个排序好的子序列合并成一个最终的排序序列。

过程图解

归并排序

代码实现

function mergeSort(arr) {merge(arr,0,arr.length-1)
}// merge其实就是合并两个有序数组,这里我们是对数组arr索引left~mid以及mid+1~right进行合并
function merge(arr,left,right){//如果起始位置比终止位置小就开启排序逻辑if(left<right){//确定中间值,将数组分成两部分let mid = Math.floor((left+right)/2)		//递归执行左侧部分的分解merge(arr,left,mid)//递归执行右侧部分的分解merge(arr,mid+1,right)//分解完毕从最后一层递归中合并//定义左部分数组和右部分数组比较的起点let [l,r] = [left,mid+1]//定义临时数组的指针let k = 0//当左侧数组和右侧数组任意一个没有走完的时候,因为分解时可能左右数组长度不一样let temp = []// 依次对比两数组的元素,谁小就谁放到前面, 直到一个数组已经走完while(l<=mid&&r<=right){temp[k++] = arr[l] >= arr[r] ? arr[r++] : arr[l++]}//当上面循环跳出时代表至少有一个数组走到头了//比较左数组是否到达终点,如果没有就继续向临时数组放值while(l<=mid){temp[k++] = arr[l++]}//比较右数组是否到达终点如果没有就继续向临时数组放值while(r<=right){temp[k++] = arr[r++]}//重制临时数组指针k = 0//从此次归并的长度范围将临时数组的排序结果放入原数组while(left<=right){arr[left++] = temp[k++]}}
}comparator.test(mergeSort);

算法分析

稳定性:我们从代码中可以看到当左边的元素小于等于右边的元素就把左边的排前面,而原本左边的就是在前面,所以相同元素的相对顺序不变,故为稳定排序
比较性:因为排序时元素之间需要比较,所以是比较排序
时间复杂度:复杂度为O(nlog^n)
空间复杂度:在合并子列时需要申请临时空间,而且空间大小随数列的大小而变化,所以空间复杂度为O(n)

6.快速排序

快速排序使用得最广泛,速度也很快,不然为啥叫快排呢,对吧。

算法思想

在所有数据中,选择一个元素作为基准
所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。

过程图解

请添加图片描述

代码实现

function quickSort(arr) {quick(arr,0,arr.length-1)
}
// 总的来说就是遍历数组,取一个基准值(上面动图取的是最右边的值,这里是取数组最中间的值),大于这个值就放右边,小于放左边
function quick(arr, left, right) {if (left >= right) {return;}// 取中间值let midVal = arr[Math.floor(left + Math.floor((right - left) / 2))];// 通过维持一个左边界和右边界let leftSide = left - 1;let rightSide = right + 1;// 设置当前值指针let cur = left;// 直到当前值指针>=等于右边界while (cur < rightSide) {// 当前值<指定值,那么把当前值和左边界的下一个值进行交换 // 然后当前值指针继续向右移,左边界也右移if (arr[cur] < midVal) {swap(arr, leftSide + 1, cur);cur++;leftSide++;} else if (arr[cur] > midVal) {// 当前值 > 指定值,那么把当前值和右边界的前面的值进行交换 // 然后右边界向左移 当前值指针保持不动swap(arr, cur, rightSide - 1);rightSide--;} else {// 当前值=指定值,当前值指针右移cur++;}}// 此时左边界以左全部小于指定值 右边界以右全部大于指定值// 然后对小于指定值的元素和大于等于指定值的元素分别进行快排quick(arr, left, leftSide);quick(arr, rightSide, right);
}comparator.test(quickSort);

算法分析

稳定性:快速排序是不稳定排序,就如我们实现的代码,排序[9,8,8]时,取中间的8为基准值,遍历到9时,与最后的8交换,不满足稳定性的概念。
比较性:因为排序时元素之间需要比较,所以是比较排序
时间复杂度:快速排序的平均时间复杂度和最坏时间复杂度分别是O(nlgn)、O(n^2)。
最好时间复杂度:O(nlogn)。每次选取分区点时,都能选中中位数,把数组等分成两个。
最坏时间复杂度:O(n^2)。每次分区都选中了最小值或最大值,得到不均等的两组。那么就需要 n 次的分区操作,每次分区平均扫描 n / 2 个元素。
空间复杂度:首先就地快速排序使用的空间是O(1)的,也就是个常数级;而真正消耗空间的就是递归调用了,因为每次递归就要保持一些数据;最优的情况下空间复杂度为:O(logn) ;每一次都平分数组的情况;最差的情况下空间复杂度为:O( n )


实际速度对比

通过我们前面写的比较器,我们可以对比各排序在各种数据规模下的排序效率

let comparator = new Comparator;
console.log("数据量为100时:")
comparator.setData(100);
comparator.test(bubbleSort);  
comparator.test(selectionSort); 
comparator.test(insertSort); 
comparator.test(shellSort); 
comparator.test(mergeSort); 
comparator.test(quickSort); 
console.log("数据量为1000时:")
comparator.setData(1000);
comparator.test(bubbleSort);  
comparator.test(selectionSort); 
comparator.test(insertSort); 
comparator.test(shellSort); 
comparator.test(mergeSort); 
comparator.test(quickSort); 
console.log("数据量为10000时:")
comparator.setData(10000);
comparator.test(bubbleSort);  
comparator.test(selectionSort); 
comparator.test(insertSort); 
comparator.test(shellSort); 
comparator.test(mergeSort); 
comparator.test(quickSort); 
console.log("数据量为100000时:")
comparator.setData(100000);
comparator.test(bubbleSort);  
comparator.test(selectionSort); 
comparator.test(insertSort); 
comparator.test(shellSort); 
comparator.test(mergeSort); 
comparator.test(quickSort); 
// 下面是控制台打印的结果
// 数据量为100时:
// bubbleSort排序正确:耗时2毫秒
// selectionSort排序正确:耗时1毫秒
// insertSort排序正确:耗时0毫秒
// shellSort排序正确:耗时0毫秒
// mergeSort排序正确:耗时0毫秒
// quickSort排序正确:耗时0毫秒
//  数据量为1000时:
// bubbleSort排序正确:耗时4毫秒
// selectionSort排序正确:耗时2毫秒
// insertSort排序正确:耗时2毫秒
// shellSort排序正确:耗时1毫秒
// mergeSort排序正确:耗时3毫秒
// quickSort排序正确:耗时0毫秒
//  数据量为10000时:
// bubbleSort排序正确:耗时201毫秒
// selectionSort排序正确:耗时64毫秒
// insertSort排序正确:耗时35毫秒
// shellSort排序正确:耗时2毫秒
// mergeSort排序正确:耗时3毫秒
// quickSort排序正确:耗时0毫秒
//  数据量为100000时:
// bubbleSort排序正确:耗时23243毫秒
// selectionSort排序正确:耗时5609毫秒
// insertSort排序正确:耗时3176毫秒
// shellSort排序正确:耗时19毫秒
// mergeSort排序正确:耗时28毫秒
// quickSort排序正确:耗时5毫秒

可以看出随着数据量规模的增大,快排,希尔,归并排序效率要远远高于冒泡,插入,选择。尤其是快排,快到飞起,牛逼。

主要就记录了这最常见的六种排序,后续学习了再更新。还请各位大佬多多指教。

引用

排序算法——(1)简介
排序算法——(2)Python实现十大常用排序算法
图解归并排序过程的JS实现【附源代码】


http://chatgpt.dhexx.cn/article/xqI1T5kM.shtml

相关文章

js-常见排序算法

目录 一、选择排序 二、冒泡排序 三、插入排序 1. 希尔排序 四、归并排序 五、快速排序 版权声明&#xff1a;本文为博主原创文章&#xff0c;若文章中有错误请联系博主改正&#xff0c;请不要恶意留言(不喜欢请绕道)。欢迎大家转载&#xff0c;转载时请注明原文地址:https://b…

3.JS排序算法之选择排序

选择排序&#xff08;selectSort&#xff09;&#xff0c;顾名思义&#xff0c;每次选择最值进行排序 目录 一、选择排序算法原理 二、选择排序算法分析 三、选择排序算法应用实例 四、选择排序的适用场景 一、选择排序算法原理 1.思路 选择排序的实现思路是从未排序序列中…

JavaScript实现十大排序算法(图文详解)

冒泡排序 排序的效果图 解法 当前解法为升序 冒泡排序的特点&#xff0c;是一个个数进行处理。第i个数&#xff0c;需要与后续的len-i-1个数进行逐个比较。 为什么是 len-i-1个数&#xff1f; 因为数组末尾的i个数&#xff0c;已经是排好序的&#xff0c;确认位置不变的了。…

JS 常见的排序算法

工作中算法不常用&#xff0c;但是排序经常用。因此在这里整理了几种JS中常见的排序算法。 冒泡排序 1、算法思想&#xff1a;判断两个相邻元素&#xff0c;大于则交换位置 2、算法步骤 从数组中第一个数开始&#xff0c;依次与下一个数比较并次交换比自己小的数&#xff0c…

详细解析十大排序算法(js实现)

详细解析十大排序算法js实现 算法概述1.冒泡排序1.1算法描述1.2动图演示1.3代码实现 2.选择排序2.1算法描述2.2动图演示2.3代码实现2.4算法分析 3.插入排序3.1算法描述3.2动图演示3.3代码实现3.4算法分析 4.希尔排序4.1算法描述4.2动图演示4.3代码实现4.4算法分析 5.归并排序5.…

Excel中使用SUMIFS公式时计算结果不正确(原因:有超过15位数字的长编码)

在使用SUMIFS公式进行多条件求和时发现求和结果部分正确&#xff0c;部分错误。 常见原因&#xff1a; 1、公式错误 2、数据格式有问题或者有空格等 仔细检查后发现并不是上述两个原因&#xff0c;而是求和的公式中涉及到超过15位数字的长编码。常见的SUMIF、SUMIFS、COUNTIF等…

mybatis-plus使用

1 mybaitsplus简介 &#xff08;1&#xff09;对于mybatis功能的增强&#xff0c;具体的体现就是对于单表的操作都生成好了&#xff0c;分页&#xff0c;条件查询使用很方便&#xff0c;例如查询操作&#xff0c;直接使用wrapper的实现类&#xff0c;调用方法进行条件的增加&a…

四、Hibernate框架的API (三)-- Session对象

一、Session对象 1.Hibernate最重要的对象,只用使用hibernate与数据库操作&#xff0c;都用到这个对象2.该对象维护了一个Connection对象。代表了与数据库连接的会话。3.该对象实质上是对Connection对象的包装&#xff0c;在Connection对象基础之上&#xff0c;封装了一些方法。…

Criteria的用法

一、Hibernate提供了5种检索对象的方式 1.导航对象图检索方式&#xff1a;根据已经加载的对象导航到其他对象    from Emp e group by e.dept.deptName 2.OID检索方式&#xff1a;按照对象的OID来检索对象   get/load 3.HQL检索方式&#xff1a;使用面向对象的HQL查询语…

第13章:处理Excel电子表格(笔记)

13.1&#xff1a;Excel文档 13.2&#xff1a;安装openpyxl模块 pip install --user --Uopenpuxl2.6.2 这是安装2.6.2版本的&#xff0c;比较新的版本与学习的书籍的信息有一点不兼容 13.3&#xff1a;读取Excel文档 13.3.1&#xff1a;用openpyxl模块打开Excel文档 import …

关于 range.autofilter 和 VBA的 filter

1 range().autofilter容易出错的地方 1.1 range().autofilter的返回值 range().autofilter 返回值总是 true返回值并不是对象&#xff0c;而是执行一个筛选的操作所以 Sub test1_filter5() Dim rng1 As Range Set rng1 Range("b1:b20").AutoFilter(field:1, Crit…

Opencv学习之角点检测

Opencv学习之角点检测 角点检测 在图像处理和计算机视觉领域&#xff0c;兴趣点&#xff08;interest points&#xff09;&#xff0c;也被称作关键点&#xff08;key points&#xff09;、特征点&#xff08;feture points&#xff09;。它被大量用于解决物体识别、图像识别…

VBA-Range.AutoFilter 方法浅析

VBA-Range.AutoFilter 方法的一些“坑” 学到筛选的时候遇到一些小小的“坑”&#xff0c;记录下。 录制出来的宏是这样的&#xff0c; Sub 宏1()宏1 宏Rows("1:1").SelectSelection.AutoFilterActiveSheet.Range("$A$1:$F$1048").AutoFilter field:4, …

Hibernate查询Query By Criterial

提供的检索方式&#xff1a;&#xff08;1&#xff09;导航对象图检索方式 &#xff08;2&#xff09;OID检索方式&#xff08;3&#xff09;HQL检索方式&#xff08;4&#xff09;QBC检索方式[query by Criteria(标准)]&#xff08;5&#xff09;本地SQL检索方式 1、简介 1.…

SLUB和SLAB的区别

转载&#xff1a;http://www.cnblogs.com/tolimit/ 首先为什么要说slub分配器&#xff0c;内核里小内存分配一共有三种&#xff0c;SLAB/SLUB/SLOB&#xff0c;slub分配器是slab分配器的进化版&#xff0c;而slob是一种精简的小内存分配算法&#xff0c;主要用于嵌入式系统。慢…

[linux kernel]slub内存管理分析(7) MEMCG的影响与绕过

文章目录 背景前情回顾描述方法约定 MEMCG总览省流总结简介 slub 相关 memcg机制kernel 5.9 版本之前结构体初始化具体实现 kernel 5.9-5.14kernel 5.14 之后 突破slab限制方法cross cache attackpage 堆风水 总结 背景 前情回顾 关于slab几个结构体的关系和初始化和内存分配…

linux slub分配器,Vi Linux内存 之 Slub分配器(六)

再来看内置式对象&#xff0c;如下图所示。指针位于对象的头部&#xff0c;与对象共用存储空间。这是因为对象被分配出去之前&#xff0c;其存储空间是空闲的可用状态&#xff0c;可用于存放空闲对象指针。对象被分配出去后&#xff0c;也不再需要这个指针了&#xff0c;可以被…

一文给你解决linux内存源码分析- SLUB分配器概述(超详细)

SLUB和SLAB的区别 首先为什么要说slub分配器&#xff0c;内核里小内存分配一共有三种&#xff0c;SLAB/SLUB/SLOB&#xff0c;slub分配器是slab分配器的进化版&#xff0c;而slob是一种精简的小内存分配算法&#xff0c;主要用于嵌入式系统。慢慢的slab分配器或许会被slub取代&…

Linux内存管理(2):SLAB/SLUB系统(基于线性映射)

一、概述 伙伴系统最大限度地解决了内存管理地外碎片问题,但是对于内碎片问题却无能为力。但内核实际使用内存的时候,却大多是小于一个页的单位。为了解决内核自身使用小块内存的碎片问题,Linux引入了基于对象的内存管理(或者叫内存区管理,Memory Area Management),就是SL…

slub分配器学习系列之linux5.10

前言 前一篇文章对 linux5.10 的 slab 分配器底层实现进行了探究与学习。进一步地&#xff0c;本篇文章将对 linux5.10 的 slub 分配器进行探究&#xff0c;对比看看两者的实现有何不同&#xff0c;做了哪些"必要的"改进。 slub 分配器 关于 slub 分配器的基本原理…