内存的分配与回收实验

2023-10-26

内存的分配与回收

北京师范大学珠海分校

实验目的

1.通过使用位图或空闲表,跟踪内存使用情况,模拟和评价不同的内存分配算法;

2.熟悉内存分配和回收管理过程。

实验要求

1.要求用你熟悉的程序设计语言编写和调试一个内存分配和回收模拟程序;要求在主函数中测试。

2.实验报告中必须包括:设计思想、数据定义(包括详细说明)、处理流程(详细算法描述和算法流程图)、源代码、运行结果、体会等部分。

3.必须模拟该4种内存分配算法:first fit,next fit,best fit和worst fit中的至少2种。

4.需显示出每次分配和回收后的空闲分区链的情况来以及内存占用情况图。

5.(可选:)计算2个性能参数:碎片数(小于2个单元(units)的空闲区数)、完成一次内存分配的空闲区比较(搜索)次数,也即经过几次比较完成某次请求的内存分配。

实验内容

假设内存容量为256KB,并且划分成1KB大小的块,也即每个内存单元为1KB。一个进程所需要的内存为3到10个单元。同时假设一个作业在运行过程中所需内存的大小不变。

模拟包括3部分:
1.实现特定的内存分配算法
2.实现内存回收模拟
3.每种内存分配策略对应的碎片数统计(可选)

实验步骤

1.确定内存空间分配表

1)数据项设计
2)存储结构确定

内存空间分配表采用双向链表的数据形式

分配空间块的数据结构为:
前向指针:before 初始值为-1 指向该结点的上一个节点的位置
进程块在内存中的位置: strtLocation 表示该内存块的位置信息
进程块id:标志被占用的内存块
空间大小 :size 表示占用内存的大小
后向指针: next 初始值为-1 表示该节点的下一个结点位置

空闲块的数据结构:
前向指针:before 初始值为-1 指向该空闲块的上一个空闲块的位置
空闲块在内存中的位置: strtLocation 表示该空闲块的位置信息
空间大小 :size 表示空闲空间的大小
后向指针: next 初始值为-1 表示该节点的下一个空闲块的位置

作业块链表数据结构

在这里插入图片描述

空闲块链表数据结构

在这里插入图片描述

2.采用某2种算法完成内存空间的分配和回收

1)算法分析
2)算法流程图绘制
3)编码
4)调试
3.编写主函数对所做工作进行测试。

分配回收算法

1.首次适应算法FirstFit——空闲链表按地址递增的次序链接,优先分配内存中低址部分的空闲区。可保留高址大空闲区。

2.循环适应算法NextFit——从上次找到的空闲分区的下一个空闲分区开始查找。应设置一起始查询指针。该算法使空闲分区分布得更均匀。

3.最佳适应算法BestFit——空闲链表按分区大小递增的次序链接,优先分配内存中满足条件的最小的空闲区。

4.最坏适应算法WorstFit——空闲链表按分区大小递减的次序链接,优先分配内存中最大的空闲区。

实现

一、首次适应算法

1.核心思想

在分配一个作业块时,按照内存中空闲块的位置依次查找,直到找到合适大小的内存块(空闲块的大小大于等于作业块的大小)

2.难点分析

在回收内存块时,内存列表会有以下三种情况:
(1)在该回收块的左右两边都有相邻的空闲块;
(2)在该回收块的左边或者右边有相邻的空闲块;
(3)在该回收块的左边和右边都没有相邻的回收块;

3.问题解决

第(1)种情况:将三个空闲块合并;
第(2)种情况:将相邻的两个空闲块合并;
第(3)种情况:将空闲块加入到空闲链表中;

4.算法流程图

分配作业块

在这里插入图片描述

回收

在这里插入图片描述

代码实现

ProcessNode类
//初始化作业块和空闲块

package com.it.bnuz.yzy;

public class ProcessNode {
    private int id;
    private int size;

    public ProcessNode(int id, int size) {
        this.id = id;
        this.size = size;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }
}

UseNode类:
//作业块

package com.it.bnuz.yzy;

public class UseNode implements Comparable<UseNode> {
    private int before = -1;//初始为-1,-1表示表头
    private int startLocation;
    private int id;
    private int size;
    private int next = -1;//初始为-1,-1表示表尾

    public UseNode(int id, int size) {
        this.id = id;
        this.size = size;
    }

    public int getBefore() {
        return this.before;
    }

    public void setBefore(int before) {
        this.before = before;
    }

    public int getStartLocation() {
        return this.startLocation;
    }

    public void setStartLocation(int startLocation) {
        this.startLocation = startLocation;
    }

    public int getId() {
        return this.id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getSize() {
        return this.size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public int getNext() { return this.next; }

    public void setNext(int next) {
        this.next = next;
    }

    public int compareTo(UseNode o) {
        return this.startLocation - o.getStartLocation();
    }

    public String toString() {
        String str = "[before:" + this.before + " startLocation:" + this.startLocation + " id:" + this.id + " size:" + this.size + " next:" + this.next + "]";
        return str;
    }
}

FreeNode类:
//空闲块

package com.it.bnuz.yzy;

public class FreeNode implements Comparable<FreeNode> {
    private int before = -1;
    private int startLocation;
    private int size;
    private int next = -1;

    public FreeNode(int size) {
        this.size = size;
    }

    public int getBefore() {
        return before;
    }

    public void setBefore(int before) {
        this.before = before;
    }

    public int getStartLocation() {
        return startLocation;
    }

    public void setStartLocation(int startLocation) {
        this.startLocation = startLocation;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public int getNext() {
        return next;
    }

    public void setNext(int next) {
        this.next = next;
    }

    @Override
    public int compareTo(FreeNode o) {
        return this.startLocation - o.getStartLocation();
    }

    @Override
    public String toString() {
        String str = "[before:"+before+" startLocation:"+startLocation+" size:"+size+" next:"+next+"]";
        return str;
    }
}

内存Map

private String[] memory_space = new String[256];

初始状态下的内存情况:
//内存空间为16 * 16 的矩形空间,大小为256k,一个单元代表1k
//0代表空闲区

在这里插入图片描述

作业链表:

private List<UseNode> useSpaceList = new ArrayList<>();

空闲链表:

private List<FreeNode> freeSpaceList = new ArrayList<>();

FirstFit分配算法:

/*
    *FirstFit首次适应算法 分配算法
    * */
    void FirstFit_distribution(ProcessNode p){
        UseNode useNode = new UseNode(p.getId(),p.getSize());
        int size = p.getSize();
        int count = 0;
        for(int i = 0; i < freeSpaceList.size();i++){//循环寻找是否有合适大小的空闲块
            count++;
            if(size <= freeSpaceList.get(i).getSize()){
                //先处理空闲快链表
                FreeNode freeNode = freeSpaceList.get(i);
                useNode.setStartLocation(freeNode.getStartLocation());//插入进的占用块结点的起始位置为这个空闲块的起始位置

                if(size < freeNode.getSize()){//插入块的大小小于该空闲块的大小时,该空闲块的起始位置发生改变,大小发生改变
                    freeSpaceList.get(i).setStartLocation(freeNode.getStartLocation() + p.getSize());
                    freeSpaceList.get(i).setSize(freeNode.getSize() - p.getSize());
                }
                else{//如果插入块的大小和该空闲块的大小相同,从链表中删除这个空闲块
                    if(i == 0){
                        freeSpaceList.get(i+1).setBefore(-1);//如果这个空闲块是表头,那么将下一个空闲块的before置为-1;
                    }
                    else{
                        freeSpaceList.get(i-1).setNext(freeSpaceList.get(i).getNext());
                        freeSpaceList.get(i+1).setBefore(freeSpaceList.get(i).getBefore());
                    }
                }
                //在内存中显示分配情况
                for(int j = useNode.getStartLocation();j < useNode.getStartLocation() + useNode.getSize();j++){
                    if(j == useNode.getStartLocation()){
                        memory_space[j] = ""+useNode.getId()+" ";
                    }
                    else{
                        memory_space[j] = "+ ";
                    }
                }
                showMemory();
                //对分配列表进行操作
                firstFit_add(useNode);
                showUseSpaceList();
                showFreeSpaceList();
                return;
            }
            else {
                continue;
            }
        }
        if(count == freeSpaceList.size()){
            System.out.println("没有合适的空闲块,插入失败");
            return;
        }
    }

分配算法中,对作业链表操作的函数:
firstFit_add(UseNode useNode)
再插入作业链表时,该作业列表的位置分为3种情况:
1.表头
2.表中
3.表尾

/*
    * firstFit加入分配空间
    * */
    private  void firstFit_add(UseNode useNode){
        //操作占用块链表
        useSpaceList.add(useNode);
        if(useSpaceList.size() > 1){
            useSpaceList.sort(UseNode::compareTo);//通过起始地址号进行排序,模拟插入链表
            for(int k = 0;k < useSpaceList.size();k++){
                if(useNode.getId() == useSpaceList.get(k).getId()){
                    if(k == 0){
                        useSpaceList.get(k).setNext(useSpaceList.get(k+1).getStartLocation());//如果该占用块插到表头,将next指向源列表的表头起始地址
                        useSpaceList.get(k+1).setBefore(0);//将原表头的before指向表头
                    }
                    else if(k == useSpaceList.size()-1){
                        useSpaceList.get(k).setBefore(useSpaceList.get(k-1).getStartLocation());
                        useSpaceList.get(k-1).setNext(useSpaceList.get(k).getStartLocation());
                    }
                    else{
                        useSpaceList.get(k).setBefore(useSpaceList.get(k-1).getStartLocation());
                        useSpaceList.get(k).setNext(useSpaceList.get(k+1).getStartLocation());

                        useSpaceList.get(k-1).setNext(useSpaceList.get(k).getStartLocation());
                        useSpaceList.get(k+1).setBefore(useSpaceList.get(k).getStartLocation());
                    }
                }
            }
        }
    }

FirstFit回收

/*
    * firstFit首次适应算法,内存空间的释放
    * 根据分配链表查找到要释放的内存空间地址
    * 在空闲内存链表中添加空闲块
    * */
    public void firstFit_free(int id){
        //查找该块的内存块
        UseNode free_node = find_useNode(id);
        if(free_node != null){
            useSpaceList.remove(free_node);
            FreeNode freeNode = new FreeNode(free_node.getSize());
            freeNode.setStartLocation(free_node.getStartLocation());
            freeSpaceList.add(freeNode);
            freeSpaceList.sort(FreeNode::compareTo);
            for(int i = 0;i < freeSpaceList.size();i++){
                if(freeSpaceList.get(i).getStartLocation() == freeNode.getStartLocation()){
                    if(i == 0){//如果该空闲块为链表的表头
                        if((freeNode.getStartLocation() + freeNode.getSize()) == freeSpaceList.get(i+1).getStartLocation()){//如果两个空闲块相邻,拓展为一块
                            freeSpaceList.get(i).setSize(freeNode.getSize() + freeSpaceList.get(i).getSize());//合并两个空闲块
                            if(freeSpaceList.get(i+1).getNext() == -1){//如果相邻块是最后一个空闲块
                                freeSpaceList.remove(freeSpaceList.get(i+1));//将相邻空闲块删除
                                setFreeSpace(freeSpaceList.get(i).getStartLocation(),freeSpaceList.get(i).getSize());
                                break;
                            }
                            else{
                                freeSpaceList.get(i).setNext(freeSpaceList.get(i+1).getNext());//将空闲块的Next指向相邻块的下一个空闲块
                                freeSpaceList.get(i+2).setBefore(freeNode.getStartLocation());//将相邻块的下一个空闲块的before指向该空闲块
                                freeSpaceList.remove(freeSpaceList.get(i+1));
                                setFreeSpace(freeSpaceList.get(i).getStartLocation(),freeSpaceList.get(i).getSize());
                                break;
                            }
                        }
                        else{//如果两个空闲块不相邻
                            freeSpaceList.get(i).setNext(freeSpaceList.get(i+1).getStartLocation());
                            freeSpaceList.get(i+1).setBefore(freeSpaceList.get(i).getStartLocation());
                            setFreeSpace(freeSpaceList.get(i).getStartLocation(),freeSpaceList.get(i).getSize());
                        }
                    }
                    else if(i == (freeSpaceList.size() - 1)){//如果该空闲块位于链表表尾
                        FreeNode beforeNode = freeSpaceList.get(i-1);//空闲快的的前结点
                        if((beforeNode.getStartLocation() + beforeNode.getSize()) == free_node.getStartLocation()){//如果两个空闲块相邻
                            freeSpaceList.get(i-1).setSize(beforeNode.getSize() + freeNode.getSize());//合并
                            freeSpaceList.remove(freeNode);
                            setFreeSpace(freeNode.getStartLocation(),freeNode.getSize());
                            break;
                        }
                    }
                    else{//该空闲块在表中
                        FreeNode beforeNode = freeSpaceList.get(i-1);
                        FreeNode nextNode = freeSpaceList.get(i+1);
                        //分三种情况讨论:三个空闲块都相邻;只与左或右节点相邻;都不相邻
                        //都相邻
                        if((beforeNode.getStartLocation() + beforeNode.getSize() == freeNode.getStartLocation()) && (freeNode.getStartLocation() + freeNode.getSize() == nextNode.getStartLocation())){
                            freeSpaceList.get(i-1).setSize(beforeNode.getSize() + freeNode.getSize() + nextNode.getSize());
                            freeSpaceList.get(i-1).setNext(nextNode.getNext());
                            freeSpaceList.remove(freeNode);
                            freeSpaceList.remove(nextNode);
                            setFreeSpace(freeNode.getStartLocation(),freeNode.getSize());
                            break;
                        }
                        //与左相邻
                        else if(beforeNode.getStartLocation() + beforeNode.getSize() == freeNode.getStartLocation()){
                            freeSpaceList.get(i-1).setSize(beforeNode.getSize()+freeNode.getSize());
                            setFreeSpace(freeNode.getStartLocation(),freeNode.getSize());
                            break;
                        }
                        //与右相邻
                        else if(freeNode.getStartLocation() + freeNode.getSize() == nextNode.getStartLocation()){
                            freeSpaceList.get(i).setSize(freeNode.getSize()+nextNode.getSize());
                            freeSpaceList.get(i).setBefore(nextNode.getBefore());
                            freeSpaceList.get(i).setNext(nextNode.getNext());
                            freeSpaceList.remove(nextNode);
                            setFreeSpace(freeNode.getStartLocation(),freeNode.getSize());
                            break;
                        }
                        //都不相邻
                        else{
                            freeSpaceList.get(i).setBefore(beforeNode.getStartLocation());
                            freeSpaceList.get(i).setNext(nextNode.getStartLocation());
                            setFreeSpace(freeNode.getStartLocation(),freeNode.getSize());
                            break;
                        }
                    }
                }
            }
            showMemory();
            showUseSpaceList();
            showFreeSpaceList();
        }
    }

查询回收块的信息函数,返回一个UseNode对象

/*
    * 通过分配链表useSpaceList查询内存块,返回该内存快的信息
    * */
    private UseNode find_useNode(int id){
        for(int i = 0;i < useSpaceList.size();i++){
            if(useSpaceList.get(i).getId() == id){
                if(useSpaceList.size() > 1){
                    if(i == useSpaceList.size()-1){
                        useSpaceList.get(i-1).setNext(-1);
                    }
                    else if(i == 0){
                        useSpaceList.get(i+1).setBefore(-1);
                    }
                    else {
                        useSpaceList.get(i-1).setNext(useSpaceList.get(i).getNext());
                        useSpaceList.get(i+1).setBefore(useSpaceList.get(i).getBefore());
                    }
                }
                return useSpaceList.get(i);
            }
        }
        return null;
    }

结果显示

分配作业块

请输入id:1
请输入占用内存大小:35

请输入id:2
请输入占用内存大小:85

请输入id:3
请输入占用内存大小:9

请输入id:4
请输入占用内存大小:21

请输入id:5
请输入占用内存大小:19

请输入id:6
请输入占用内存大小:23

请输入id:7
请输入占用内存大小:15

请输入id:8
请输入占用内存大小:3

请输入id:9
请输入占用内存大小:6

分配后的内存情况:

在这里插入图片描述

分配后的作业块链表:

在这里插入图片描述

分配后的空闲快链表:

在这里插入图片描述

回收

回收id=5的作业块

在这里插入图片描述

作业链表:

在这里插入图片描述

空闲块链表:

在这里插入图片描述

两边都有空闲块的情况:

回收前

在这里插入图片描述

回收后

在这里插入图片描述

作业块链表

在这里插入图片描述

空闲快链表

在这里插入图片描述

再插入

在这里插入图片描述
在这里插入图片描述

二、循环适应算法

1.核心思想

在空闲块列表中加标记。在插入一个作业块时,从上一次标记的空闲块的下一个空闲块开始查找合适的空闲块进行插入。

2.算法流程图

在这里插入图片描述
回收算法的流程与first fit一致,这里就不做重复了。

3.代码实现

nextFit算法,这里只给出核心的分配算法,插入作业链表和插入空闲链表的算法与上述一致。

    /*
     * NextFit算法 循环适应算法
     * */
    public int nextFit_distribution(ProcessNode p,int flag){
        UseNode useNode = new UseNode(p.getId(),p.getSize());
        int size = p.getSize();
        int count = 0;
        for(int i = flag; i < freeSpaceList.size();i++){//从上一次插入的空闲块的下一个空闲块开始循环寻找是否有合适大小的空闲块
            count++;
            if(size <= freeSpaceList.get(i).getSize()){
                //先处理空闲快链表
                FreeNode freeNode = freeSpaceList.get(i);
                useNode.setStartLocation(freeNode.getStartLocation());//插入进的占用块结点的起始位置为这个空闲块的起始位置

                if(size < freeNode.getSize()){//插入块的大小小于该空闲块的大小时,该空闲块的起始位置发生改变,大小发生改变
                    freeSpaceList.get(i).setStartLocation(freeNode.getStartLocation() + p.getSize());
                    freeSpaceList.get(i).setSize(freeNode.getSize() - p.getSize());
                }
                else{//如果插入块的大小和该空闲块的大小相同,从链表中删除这个空闲块
                    if(i == 0){
                        freeSpaceList.get(i+1).setBefore(-1);//如果这个空闲块是表头,那么将下一个空闲块的before置为-1;
                    }
                    else{
                        freeSpaceList.get(i-1).setNext(freeSpaceList.get(i).getNext());
                        freeSpaceList.get(i+1).setBefore(freeSpaceList.get(i).getBefore());
                    }
                }
                //在内存中显示分配情况
                for(int j = useNode.getStartLocation();j < useNode.getStartLocation() + useNode.getSize();j++){
                    if(j == useNode.getStartLocation()){
                        memory_space[j] = ""+useNode.getId()+" ";
                    }
                    else{
                        memory_space[j] = "+ ";
                    }
                }
                showMemory();
                //对分配列表进行操作
                addSpaceList(useNode);
                showUseSpaceList();
                showFreeSpaceList();
                if(i == freeSpaceList.size()-1){//如果该空闲块是最后一个空闲块,将flag置为0
                    flag = 0;
                }
                else {//否则将flag指向下一个空闲块
                    flag = i + 1;
                }
                return flag;
            }
            else {
                continue;
            }
        }
        if(count == freeSpaceList.size() - flag){
            System.out.println("没有合适的空闲块,插入失败");
        }
        return flag;
    }

4.结果显示

内存初始情况和链表情况:

在这里插入图片描述
在这里插入图片描述

插入作业块:

请输入id:2
请输入占用内存大小:15
在这里插入图片描述
在这里插入图片描述

插入的空闲块的位置是第一个空闲块,那么在下次插入时从第2个开始找

插入第二个作业块:

在这里插入图片描述

在这里插入图片描述

分配到了上次分配的空闲块的下一个空闲块

插入大小为30的作业块:

请输入id:6
请输入占用内存大小:30
在这里插入图片描述

再进行插入,回到第一个空闲块

在这里插入图片描述
此时的链表情况
在这里插入图片描述

完整项目下载地址

内存分配和释放完整项目包

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

内存的分配与回收实验 的相关文章

随机推荐

  • unicloud 发布后小程序提示连接本地调试服务失败,请检查客户端是否和主机在同一局域网下

    1 hbuildx中小程序控制台切换连接方式 连接云端云函数 2 本地调试的话 连接本地云函数 并确定是否启动
  • 在eclipse的project explorer不小心删除了servers文件夹解决办法

    在eclipse的project explorer不小心删除了servers文件夹 解决办法 在Servers中删除tomcat 重新关联link一下就恢复了 但是得把build path的旧的server文件夹remove 再重新添加
  • 我们研究了853场世界杯比赛,发现了这几条稳赔不赚的竞猜攻略

    本文转载自大数据 ID hzdashuju 导读 世界杯开赛以来 据数据叔不完全统计 身边有66 6 的小伙伴上了天台 其中22 2 的人买了阿根廷赢 22 2 的人买了德国赢 还有22 2 的人买了巴西赢 剩下那33 4 的人 总是在问数
  • Unity性能优化

    Unity性能优化专栏第一期 目录 Unity性能优化专栏第一期 橙子前言 一 性能优化概念 Unity 3D 游戏优化瓶颈归根结底是开发过程中内存分配和使用不佳的结果 1 它们承担了它们这个级别不应该有的压力 2 它们没有受到应有的尊重
  • Arduino串口通信

    文章目录 通信类型 Arduino串口通信 硬串口 软串口 通信类型 通信是用来在不同电子设备之间交换数据用的技术 其实就是要实现不同电子设备之间的 通讯对话 Arduino串口通信 Arduino采用USART通信模式 可以有硬串口 软串
  • unity中动画控制器基础知识

    动画控制器的创建 1 在工程视图里 Create Aniamtor Contorller动画控制器 命名 双击 这时会在Animator视图中显示默认有三种状态 Entry 进入状态 Any State 任意状态 Exit 退出状态 如何添
  • OpenWRT 分流DNS的设置

    文章出处 OpenWRT 分流DNS的设置 Issue 57 luckyyyyy blog 我自己根据实际需要基于上方的链接内容进行了相关补充 OpenWRT配置IPv6的方法参考如下文章 OpenWRT IPv6 NAT配置 目前还是有许
  • servlet(二)文件的上传

    servlet实现文件的上传 文件上传是一个web应用常见的功能 比如 QQ头像 就使用了上传 邮箱中也有附件的上传和下载功能 OA系统中审批有附件材料的上传 1 1前端需要有个form表单标签 method post请求 因为post请求
  • 【MATLAB】最短路径Dijkstra算法

    目录 1 Dijkstra算法 1 1使用范围 1 2算法思路 1 3实例 2 代码 2 1dijstra函数 2 2调用函数 1 Dijkstra算法 1 1使用范围 bullet 寻求从一固定顶点到其余各点的最短路径
  • 实用Javascript 传值, 数据验证, 事件触发总结

    实用Javascript 传值 数据验证 事件触发总结 1 和JSP传值问题 1 普通提交form 的数据验证传值 html页面输入
  • :aftr和 :: after区别,顺便谈一谈CSS的伪类和伪元素

    在搞小程序的时时候会用到人家的组件button 人家弄了这个组件必然会设置一些默认值 比如边框 要想把这个边框弄没 就要用一下button after这个来处理一下 类似下面这样 button after border none 这时候 a
  • C语言里字符串的解析

    转自 https blog csdn net Code star one article details 78260482 函数名称 strtok 函数原型 char strtok char s1 const char s2 函数功能 分解
  • flink入门了解

    在线工程 在机器学习场景下 在线离线处理也会面临一些问题 首先会将离线的数据进行预处理和特征工程 如红框标注所示 然后进行离线的模型训练 训练好的模型会推到线上做推理 推理模块加载模型后 在线的数据也会有进行预处理和特征工程的过程 将处理之
  • lpr或商转公

    减少房贷的两种方法 1 央妈在2019推出lpr lpr你可以看作是根据市场变化的利率 如果你认为未来经济下行 利率下降 则你可以选择这个lpr作为房贷利率 否则则相反 lpr申请在2020 8月前都可以 后面就会根据lpr来还房贷 2 还
  • 介绍 Docker 的基本概念和优势,以及在应用程序开发中的实际应用

    Docker是一种基于容器的虚拟化技术 它可以将应用程序及其依赖包装成一个独立的容器 使其可以在不同的平台上进行移植和部署 Docker的基本概念包括镜像 容器 仓库和服务 镜像是Docker应用程序的基础 包括应用程序及其依赖的组件 容器
  • Unity创建脚本显示自己的名字以及时间

    using UnityEngine using System IO using System Text using System public class QHF Editor UnityEditor AssetModificationPr
  • 服务器 winsock修复,服务器/客户端:winsock 编程初体验

    服务器 客户端 winsock 编程初体验 前日看到听风大哥的帖子 写的是windows下的C S程序的简易示例代码 顿时有了感觉 以前在linux下写过 但是不知道如何去实际应用 便放在了一边 昨晚认真的拜读 改写了一下 今日记录下来 作
  • 类和对象总结一

    话不多说 我们直接进入主题 对象 客观世界里的一切事物都可以看作是一个对象 每一个对象应当具有属性 静态特征 比如一个班级 一个专业 一个教室 和行为 动态特征 例如 学习 开会 体育比赛等 两个要素 对象是由一组属性和一组行为构成的 类
  • 快来打造属于自己的天猫精灵

    看了天猫精灵的介绍 是不是觉得很神奇 实际每个程序要都可以打造属于自己的智能家居 可以实现的功能 点歌 最基础的功能了 可以将自己喜欢的歌曲下载下来 随时点歌 定时提醒 提醒自己吃饭 提醒自己睡觉 听故事 可以通过指令让其在线搜索小故事 然
  • 内存的分配与回收实验

    内存的分配与回收 北京师范大学珠海分校 实验目的 1 通过使用位图或空闲表 跟踪内存使用情况 模拟和评价不同的内存分配算法 2 熟悉内存分配和回收管理过程 实验要求 1 要求用你熟悉的程序设计语言编写和调试一个内存分配和回收模拟程序 要求在