内存分配---FF、BF、WF三种算法

动态分区分配是根据进程的实际需要,动态的为之分配内存空间。而在实现可变分区分配时,将涉及到分区分配中

所用的数据结构、分区分配算法和分区的分配与内存回收的过程。

分区分配中的数据结构:(1)描述空闲块的数据结构。(2)内存块的描述。

#define PROCESS_NAME_LEN 32    //进程名长度
#define MIN_SLICE 10           //最小碎片的大小
#define DEFAULT_MEM_SIZE 1024  //内存大小
#define DEFAULT_MEM_START 0    //起始位置
//内存分配算法
#define MA_FF 1
#define MA_BF 2
#define MA_WF 3
//描述每一个空闲块的数据结构
struct free_block_type
{
    int size;                      //空闲块大小
    int start_addr;                //空闲块起始位置
    struct free_block_type *next;  //指向下一个空闲块
};
//指向内存中空闲块链表的首地址
struct free_block_type *free_block= NULL;
//每个进程分配到的内存块的描述
struct allocated_block
{
    int pid;
    int size;         //进程大小
    int start_addr;   //进程分配到的内存块的起始地址
    char process_name[PROCESS_NAME_LEN];  //进程名
    struct allocated_block *next;         //指向下一个进程控制块
};
//进程分配内存块链表的首指针
struct allocated_block *allocated_block_head= NULL;
int free_block_count= 0;          //空闲块的个数
int mem_size= DEFAULT_MEM_SIZE;   //内存大小
int current_free_mem_size= 0;     //当前空闲内存大小
int ma_algorithm= MA_FF;          //当前分配算法
static int pid= 0;
int flag= 0;                      //设置内存大小标志,表示内存大小是否设置

分区分配算法:

(1)首次适应算法(First Fit):从空闲分区表的第一个表目起查找该表,把最先能够满足要求的空闲区分配给

作业,这种方法的目的在于减少查找时间。为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到

高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高地址空间保留大的空闲区。

(2)最佳适应算法(Best Fit):从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区,这种方法能使

碎片尽量小。为适应此算法,空闲分区表(空闲区链)中的空闲分区要按从小到大进行排序,自表头开始查找到第一

个满足要求的自由分区分配。该算法保留大的空闲区,但造成许多小的空闲区。

(3)最差适应算法(Worst Fit):从全部空闲区中找出能满足作业要求的、且大小最大的空闲分区,从而使链表中

的结点大小趋于均匀,适用于请求分配的内存大小范围较窄的系统。为适应此算法,空闲分区表(空闲区链)中的空

闲分区按大小从大到小进行排序,自表头开始查找到第一个满足要求的自由分区分配。该算法保留小的空闲区,尽量

减少小的碎片产生。

下面是进行以上三种算法的实现:

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <unistd.h>

#define PROCESS_NAME_LEN 32    //进程名长度
#define MIN_SLICE 10           //最小碎片的大小
#define DEFAULT_MEM_SIZE 1024  //内存大小
#define DEFAULT_MEM_START 0    //起始位置
//内存分配算法
#define MA_FF 1
#define MA_BF 2
#define MA_WF 3
//描述每一个空闲块的数据结构
struct free_block_type
{
    int size;        //空闲块大小
    int start_addr;  //空闲块起始位置
    struct free_block_type *next;  //指向下一个空闲块
};
//指向内存中空闲块链表的首地址
struct free_block_type *free_block= NULL;
//每个进程分配到的内存块的描述
struct allocated_block
{
    int pid;
    int size;         //进程大小
    int start_addr;   //进程分配到的内存块的起始地址
    char process_name[PROCESS_NAME_LEN];  //进程名
    struct allocated_block *next;   //指向下一个进程控制块
};
//进程分配内存块链表的首指针
struct allocated_block *allocated_block_head= NULL;
int free_block_count= 0;          //空闲块的个数
int mem_size= DEFAULT_MEM_SIZE;   //内存大小
int current_free_mem_size= 0;     //当前空闲内存大小
int ma_algorithm= MA_FF;          //当前分配算法
static int pid= 0;
int flag= 0;                      //设置内存大小标志,表示内存大小是否设置

struct free_block_type* init_free_block(int mem_size);
void display_menu();
int set_mem_size();
void set_algorithm();
void rearrange(int algorithm);
int rearrange_WF();
int rearrange_BF();
int rearrange_FF();
int new_process();
int allocate_mem(struct allocated_block *ab);
void kill_process();
int free_mem(struct allocated_block *ab);
int dispose(struct allocated_block *free_ab);
int display_mem_usage();
struct allocated_block* find_process(int pid);
int do_exit();
int allocate_FF(struct allocated_block *ab);
int allocate_BF(struct allocated_block *ab);
int allocate_WF(struct allocated_block *ab);
int allocate(struct free_block_type *pre,struct free_block_type *allocate_free_nlock,struct allocated_block *ab);
int mem_retrench(struct allocated_block *ab);

//通过内存紧缩技术给新进程分配内存空间
int mem_retrench(struct allocated_block *ab)
{
    struct allocated_block *allocated_work,*allocated_pre= allocated_block_head;
    struct free_block_type *free_work,*free_pre= free_block->next;
    if(allocated_pre== NULL)
        return -1;
    allocated_pre->start_addr= 0;
    allocated_work= allocated_pre->next;
    while(allocated_work!= NULL)
    {
        allocated_work->start_addr= allocated_pre->start_addr+ allocated_pre->size;
        allocated_pre= allocated_work;
        allocated_work= allocated_work->next;
    }
    free_block->start_addr= allocated_pre->start_addr+ allocated_pre->size;
    free_block->size= current_free_mem_size;
    free_work= free_pre;
    while(free_pre!= NULL)
    {
        free(free_pre);
        free_pre= free_work;
        if(free_pre!= NULL)
            free_work= free_work->next;
    }
    allocate(NULL,free_block,ab);
    return 1;
}

//给新进程分配内存空间
int allocate(struct free_block_type *pre,struct free_block_type *allocate_free_block,struct allocated_block *ab)
{
    struct allocated_block *p= allocated_block_head;
    ab->start_addr= allocate_free_block->start_addr;
    if(allocate_free_block->size-ab->size< MIN_SLICE)
    {
        ab->size= allocate_free_block->size;
        if(pre!= NULL)
        {
            pre->next= allocate_free_block;
        }
        else
        {
            free_block= allocate_free_block->next;
        }
        free(allocate_free_block);
    }
    else
    {
        allocate_free_block->start_addr+= ab->size;
        allocate_free_block->size-= ab->size;
    }
    if(p== NULL)
    {
        allocated_block_head= ab;
    }
    else
    {
        while(p->next!= NULL)
            p= p->next;
        p->next= ab;
    }
    current_free_mem_size-= ab->size;
    if(current_free_mem_size== 0)
        free_block= NULL;
    return 0;
}

//按照最坏适应算法给新进程分配内存空间
int allocate_WF(struct allocated_block *ab)
{
    int ret;
    struct free_block_type *wf= free_block;
    if(wf== NULL)
        return -1;
    if(wf->size>= ab->size)
        allocate(NULL,wf,ab);
    else if(current_free_mem_size>= ab->size)
        ret= mem_retrench(ab);
    else
        ret= -2;
    rearrange_WF();
    return ret;
}

//按照最佳适应算法给新进程分配内存空间
int allocate_BF(struct allocated_block *ab)
{
    int ret;
    struct free_block_type *pre= NULL,*bf= free_block;
    if(bf== NULL)
        return -1;
    while(bf!= NULL)
    {
        if(bf->size>= ab->size)
        {
            ret= allocate(pre,bf,ab);
            break;
        }
        pre= bf;
        pre= pre->next;
    }
    if(bf== NULL&&current_free_mem_size> ab->size)
        ret= mem_retrench(ab);
    else
        ret= -2;
    rearrange_BF();
    return ret;
}

//按照首次适应算法给新进程分配内存空间
int allocate_FF(struct allocated_block *ab)
{
    int ret;
    struct free_block_type *pre= NULL,*ff= free_block;
    if(ff== NULL)
        return -1;
    while(ff!= NULL)
    {
        if(ff->size>= ab->size)
        {
            ret= allocate(pre,ff,ab);
            break;
        }
        pre= ff;
        pre= pre->next;
    }
    if(ff== NULL&&current_free_mem_size> ab->size)
        ret= mem_retrench(ab);
    else
        ret= -2;
    rearrange_FF();
    return ret;
}

//分配内存模块
int allocate_mem(struct allocated_block *ab)
{
    int ret;
    struct free_block_type *fbt,*pre;
    int request_size= ab->size;
    fbt= pre= free_block;
    switch(ma_algorithm)
    {
        case MA_FF:
            ret= allocate_FF(ab);
            break;
        case MA_BF:
            ret= allocate_BF(ab);
            break;
        case MA_WF:
            ret= allocate_WF(ab);
            break;
        default:
            break;
    }
    return ret;
}

//创建一个新进程
int new_process()
{
    struct allocated_block *ab;
    int size;
    int ret;
    ab= (struct allocated_block*)malloc(sizeof(struct allocated_block));
    if(!ab)
        exit(-5);
    ab->next= NULL;
    pid++;
    sprintf(ab->process_name,"PROCESS-%02d",pid);//将格式化的数据写入某字符串中
    ab->pid= pid;
    printf("Memory for %s:",ab->process_name);
    for(;;)
    {
        scanf("%d",&size);
        getchar();
        if(size> 0)
        {
            ab->size= size;
            break;
        }
        else
            printf("The size have to greater than zero!Please input again!");
    }
    ret= allocate_mem(ab);
    if((ret== 1)&&(allocated_block_head== NULL))  //如果此时未赋值,则赋值
    {
        allocated_block_head= ab;
        return 1;
    }
    else if(ret== 1)  //分配成功,将该已分配块的描述插入已分配链表
    {
        ab->next= allocated_block_head;
        allocated_block_head= ab;
        return 2;
    }
    else if(ret== -1)  //分配不成功
    {
        printf("Allocation fail.\n");
        free(ab);
        return -1;
    }
    return 3;
}

//退出程序并释放空间
int do_exit()
{
    struct allocated_block *allocated_ab,*allocated_pre;
    struct free_block_type *free_ab,*free_pre;
    free_pre= free_block;
    allocated_pre= allocated_block_head;
    if(free_pre!= NULL)
    {
        free_ab= free_pre->next;
        while(free_ab!= NULL)
        {
            free(free_pre);
            free_pre= free_ab;
            free_ab= free_ab->next;
        }
    }
    if(allocated_pre!= NULL)
    {
        allocated_ab= allocated_pre->next;
        while(allocated_ab!= NULL)
        {
            free(allocated_pre);
            allocated_pre= allocated_ab;
            allocated_ab= allocated_ab->next;
        }
    }
    allocated_ab= allocated_ab->next;
    return 0;
}

//在进程分配链表中寻找指定进程
struct allocated_block* find_process(int pid)
{
    struct allocated_block *ab= allocated_block_head;
    if(ab== NULL)
    {
        printf("Here?111\n");
        return NULL;
    }
    while(ab->pid!= pid&&ab->next!= NULL)
        ab= ab->next;
    if(ab->next== NULL&&ab->pid!= pid)
    {
        printf("Here?222\n");
        return NULL;
    }
    return ab;
}

//显示当前内存的使用情况,包括空闲区的情况和已经分配的情况
int display_mem_usage()
{
    struct free_block_type *fbt= free_block;
    struct allocated_block *ab= allocated_block_head;
    printf("-------------------------------------------------------------\n");
    printf("Free Memory:\n");
    printf("%20s %20s\n","     start_addr","     size");
    while(fbt!= NULL)
    {
        printf("%20d %20d\n",fbt->start_addr,fbt->size);
        fbt= fbt->next;
    }
    printf("\nUsed Memory:\n");
    printf("%10s %20s %10s %10s\n","PID","ProcessName","start_addr","size");
    while(ab!= NULL)
    {
        printf("%10d %20s %10d %10d\n",ab->pid,ab->process_name,ab->start_addr,ab->size);
        ab= ab->next;
    }
    printf("-------------------------------------------------------------\n");
    return 1;
}

//释放ab数据结构结点
int dispose(struct allocated_block *free_ab)
{
    struct allocated_block *pre,*ab;
    if(free_block== NULL)
        return -1;
    if(free_ab== allocated_block_head)   //如果要释放第一个结点
    {
        allocated_block_head= allocated_block_head->next;
        free(free_ab);
    }
    else
    {
        pre= allocated_block_head;
        ab= allocated_block_head->next;
        //找到free_ab
        while(ab!= free_ab)
        {
            pre= ab;
            ab= ab->next;
        }
        pre->next= ab->next;
        free(ab);
    }
    return 1;
}

//将ab所表示的已分配区归还,并进行可能的合并
int free_mem(struct allocated_block *ab)
{
    int algorithm= ma_algorithm;
    struct free_block_type *fbt,*pre,*work;
    fbt= (struct free_block_type*)malloc(sizeof(struct free_block_type));
    if(!fbt)
        return -1;
    pre= free_block;
    fbt->start_addr= ab->start_addr;
    fbt->size= ab->size;
    fbt->next= NULL;
    if(pre!= NULL)
    {
        while(pre->next!= NULL)
            pre= pre->next;
        pre->next= fbt;
    }
    else
    {
        free_block= fbt;
    }
    rearrange_FF();
    pre= free_block;
    work= pre->next;
    while(work!= NULL)
    {
        if(pre->start_addr+ pre->size== work->start_addr)
        {
            pre->size+= work->size;
            free(work);
            work= pre->next;
        }
        else
        {
            pre= work;
            work= work->next;
        }
    }
    current_free_mem_size+= ab->size;
    return 1;
}

//删除进程,归还分配的存储空间,并删除描述该进程内存分配的结点
void kill_process()
{
    struct allocated_block *ab;
    int pid;
    printf("Kill Process,pid=");
    scanf("%d",&pid);
    getchar();
    ab= find_process(pid);
    if(ab!= NULL)
    {
        free_mem(ab);  //释放ab所表示的分配区
        dispose(ab);   //释放ab数据结构结点
    }
}

//按FF算法重新整理内存空闲块链表,按空闲块首地址排序
int rearrange_FF()
{
    struct free_block_type *head= free_block;
    struct free_block_type *forehand,*pre,*rear;
    int i;
    if(head== NULL)
        return -1;
    for(i= 0;i< free_block_count-1;i++)
    {
        forehand= head;
        pre= forehand->next;
        rear= pre->next;
        while(pre->next!= NULL)
        {
            if(forehand== head&&forehand->start_addr>= pre->start_addr)
            {
                //比较空闲链表中第一个空闲块与第二个空闲块的开始地址的大小
                head->next= pre->next;
                pre->next= head;
                head= pre;
                forehand= head->next;
                pre= forehand->next;
                rear= pre->next;
            }
            else if(pre->start_addr>= rear->start_addr)
            {
                //比较链表中其它相邻两个结点的开始地址的大小
                pre->next= rear->next;
                forehand->next= rear;
                rear->next= pre;
                forehand= rear;
                rear= pre->next;
            }
            else
            {
                forehand= pre;
                pre= rear;
                rear= rear->next;
            }
        }
    }
    return 0;
}

//按BF算法重新整理内存空闲块链表,按空闲块大小从小到大排序
int rearrange_BF()
{
    struct free_block_type *head= free_block;
    struct free_block_type *forehand,*pre,*rear;
    int i;
    if(head== NULL)
        return -1;
    for(i= 0;i< free_block_count-1;i++)
    {
        forehand= head;
        pre= forehand->next;
        rear= pre->next;
        while(pre->next!= NULL)
        {
            if(forehand== head&&forehand->size<= pre->size)
            {
                //比较空闲链表中第一个空闲块与第二个空闲块的空间的大小
                head->next= pre->next;
                pre->next= head;
                head= pre;
                forehand= head->next;
                pre= forehand->next;
                rear= pre->next;
            }
            else if(pre->size<= rear->size)
            {
                //比较链表中其它相邻两个结点的空间的大小
                pre->next= rear->next;
                forehand->next= rear;
                rear->next= pre;
                forehand= rear;
                rear= pre->next;
            }
            else
            {
                forehand= pre;
                pre= rear;
                rear= rear->next;
            }
        }
    }
    return 0;
}

//按WF算法重新整理内存空闲块链表,按空闲块大小从大到小排序
int rearrange_WF()
{
    struct free_block_type *head= free_block;
    struct free_block_type *forehand,*pre,*rear;
    int i;
    if(head== NULL)
        return -1;
    for(i= 0;i< free_block_count-1;i++)
    {
        forehand= head;
        pre= forehand->next;
        rear= pre->next;
        while(pre->next!= NULL)
        {
            if(forehand== head&&forehand->size>= pre->size)
            {
                //比较空闲链表中第一个空闲块与第二个空闲块空间的大小
                head->next= pre->next;
                pre->next= head;
                head= pre;
                forehand= head->next;
                pre= forehand->next;
                rear= pre->next;
            }
            else if(pre->size>= rear->size)
            {
                //比较链表中其它相邻两个结点的空间的大小
                pre->next= rear->next;
                forehand->next= rear;
                rear->next= pre;
                forehand= rear;
                rear= pre->next;
            }
            else
            {
                forehand= pre;
                pre= rear;
                rear= rear->next;
            }
        }
    }
    return 0;
}

//按指定的算法整理内存空闲块链表
void rearrange(int algorithm)
{
    switch(algorithm)
    {
        case MA_FF:
            rearrange_FF();
            break;
        case MA_BF:
            rearrange_BF();
            break;
        case MA_WF:
            rearrange_WF();
            break;
    }
}

//设置当前的分配算法
void set_algorithm()
{
    int algorithm;
    //system("clear");
    printf("\t1-First Fit\n");   //首次适应算法
    printf("\t2-Best Fit\n");    //最佳适应算法
    printf("\t3-Worst Fit\n");   //最坏适应算法
    printf("Please choose(1-3):");
    for(;;)
    {
        scanf("%d",&algorithm);
        getchar();
        if(algorithm>= 1&&algorithm<= 3)
        {
            ma_algorithm= algorithm;
            break;
        }
        else
        {
            printf("\nCannot input %d,Please input 1-3:",algorithm);
        }
    }
    rearrange(ma_algorithm);
}

//设置内存的大小
int set_mem_size()
{
    int size;
    if(flag!= 0)     //防止重复设置
    {
        printf("Cannont set memory size again\n");
        return 0;
    }
    printf("Total memory size=");
    for(;;)
    {
        scanf("%d",&size);
        getchar();
        if(size> 0)
        {
            current_free_mem_size= size;
            mem_size= size;
            free_block->size= mem_size;
            break;
        }
        else
        {
            printf("The size must greater than zero!Please input again:");
        }
    }
    flag= 1;    //内存大小已经设置
    return 1;
}

//显示主菜单
void display_menu()
{
    printf("\n");
    //system("clear");
    printf("1-Set memory size(default= %d)\n",DEFAULT_MEM_SIZE);
    printf("2-Select memory allocation algorithm\n");
    printf("3-New process\n");
    printf("4-Terminate a process\n");
    printf("5-Display memory usage\n");
    printf("0-Exit\n");
}

//初始化空闲块,默认为一块,可以指定大小及起始地址
struct free_block_type* init_free_block(int mem_size)
{
    struct free_block_type *fb;
    fb= (struct free_block_type*)malloc(sizeof(struct free_block_type));
    if(fb== NULL)
    {
        printf("No mem\n");
        return NULL;
    }
    current_free_mem_size= mem_size;
    fb->size= mem_size;
    fb->start_addr= DEFAULT_MEM_START;
    fb->next= NULL;    //首地址指向NULL
    return fb;
}

int main()
{
    char choice;
    pid= 0;
    free_block= init_free_block(mem_size);
    while(1)
    {
        display_menu();
        fflush(stdin);
        choice= getchar();
        getchar();
        switch(choice)
        {
            case ‘1‘:     //设置内存大小
                set_mem_size();
                break;
            case ‘2‘:     //设置算法
                set_algorithm();
                flag= 1;
                break;
            case ‘3‘:     //创建新进程
                new_process();
                flag= 1;
                break;
            case ‘4‘:     //删除进程
                kill_process();
                flag= 1;
                break;
            case ‘5‘:     //显示内存使用
                display_mem_usage();
                flag= 1;
                break;
            case ‘0‘:     //释放链表并退出
                do_exit();
                exit(0);
            default:
                break;
        }
    }
}

原文地址:https://www.cnblogs.com/XNQC1314/p/9065236.html

时间: 2024-10-11 06:34:35

内存分配---FF、BF、WF三种算法的相关文章

缓存算法(FIFO 、LRU、LFU三种算法的区别)

缓存算法(FIFO .LRU.LFU三种算法的区别) FIFO算法# FIFO 算法是一种比较容易实现的算法.它的思想是先进先出(FIFO,队列),这是最简单.最公平的一种思想,即如果一个数据是最先进入的,那么可以认为在将来它被访问的可能性很小.空间满的时候,最先进入的数据会被最早置换(淘汰)掉. FIFO 算法的描述:设计一种缓存结构,该结构在构造时确定大小,假设大小为 K,并有两个功能: set(key,value):将记录(key,value)插入该结构.当缓存满时,将最先进入缓存的数据置

Java利用 DES / 3DES / AES 这三种算法分别实现 对称加密

转载请注明出处:http://blog.csdn.net/smartbetter/article/details/54017759 有两句话是这么说的: 1)算法和数据结构就是编程的一个重要部分,你若失掉了算法和数据结构,你就把一切都失掉了. 2)编程就是算法和数据结构,算法和数据结构是编程的灵魂. 注意,这可不是我说的,是无数程序员总结的,话说的很实在也很精辟,若想长久可持续发展,多研究算法还是很有必要的,今天我给大家说说加密算法中的对称加密算法,并且这里将教会大家对称加密算法的编程使用.包含

最近公共祖先(三种算法)

最近研究了一下最近公共祖先算法,根据效率和实现方式不同可以分为基本算法.在线算法和离线算法.下面将结合hihocoder上的题目分别讲解这三种算法. 1.基本算法 对于最近公共祖先问题,最容易想到的算法就是从根开始遍历到两个查询的节点,然后记录下这两条路径,两条路径中距离根节点最远的节点就是所要求的公共祖先. 题目参见 #1062 : 最近公共祖先·一 附上AC代码,由于记录的方式采取的是儿子对应父亲,所以实现的时候有点小技巧,就是对第一个节点的路径进行标记,查找第二个节点的路径时一旦发现访问到

Opencv——彩色图像灰度化的三种算法

为了加快处理速度在图像处理算法中,往往需要把彩色图像转换为灰度图像.24为彩色图像每个像素用3个字节表示,每个字节对应着RGB分量的亮度. 当RGB分量值不同时,表现为彩色图像:当RGB分量相同时,变现为灰度图像: 一般来说,转换公式有3中. (1)Gray(i,j)=[R(i,j)+G(i,j)+B(i,j)]/3; (2)Gray(i,j)=0.299*R(i,j)+0.587*G(i,j)+0.144*B(i,j); (3)Gray(i,j)=G(i,j);//从2可以看出G的分量比较大所

快速排序、归并排序、堆排序三种算法性能比较

快速排序.归并排序.堆排序三种排序算法的性能谁最好呢?网上查了一下说快速排序最快.其次是归并排序,最差的是堆排序:而理论上三种排序算法的时间复杂度都是O(nlogn),只不过快速排序最差的会达到O(n^2),但是数据的随机性会消除这一影响,今天就来实际比较一下: 1 #include <iostream> 2 #include<time.h> 3 using namespace std; 4 #define MAX 100000000 5 int data1[MAX],data2[

字符串匹配的三种算法

下面将介绍三种有关字符串匹配的算法,一种是朴素的匹配算法,时间复杂度为O(mn),也就是暴力求解.这种方法比较简单,容易实现.一种是KMP算法,时间复杂度为O(m+n),该算法的主要任务是求模式串的next数组.另外还有一种对KMP算法的改进,主要是求nextval数组. 第一种朴素的匹配算法: int index(char str[], char subStr[]) { int i = 0, j = 0,index = 0; while (str[i] != '\0' && subStr

Java常用三种算法排序比较

Java常用三种算法排序比较 冒泡排序: package demo1; /** * * @author xiaoye 2014-5-13 */ /** * 有N 个数据需要排序,则从第0 个数开始,依次比较第0 和第1 个数据, * 如果第0 个大于第1 个则两者交换,否则什么动作都不做,继续比较第 1 个第2个-, * 这样依次类推,直至所有数据都"冒泡"到数据顶上. 冒泡排序的效率 O(N*N ),比较 N*N/2 ,交换N*N/4 . */ public class Bubble

JVM内存分配策略,及垃圾回收算法

本人免费整理了Java高级资料,一共30G,需要自己领取;传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 说起垃圾收集(Garbage Collection, GC),想必大家都不陌生,它是JVM实现里非常重要的一环,JVM成熟的内存动态分配与回收技术使Java(当然还有其他运行在JVM上的语言,如Scala等)程序员在提升开发效率上获得了惊人的便利.理解GC,对于理解JVM和Java语言有着非常重要的作用.并且当我们需要排查各种内存溢

字符串相似度三种算法介绍

余弦相似度 计算公式为: P(A,B) = sqrt(A × B) / (|A| × |B|) 设有两个字符串: ABCDEFG ABCHIJK 其中共有11个字符,为: A B C D E F G H I J K 如果,不考虑他们之间的关联性以及顺序等隐私,那么可以讲这两个字符串转换成两个11维空间中的向量: {1.1.1.1.1.1.1.0.0.0.0} {1.1.1.0.0.0.0.1.1.1.1} 那,计算他们之间的相似度为: P = sqrt(3) / (sqrt(7) × sqrt(