Go运行时的内存分配器以及消耗指定大小的内存(C语言)

news2025/8/7 6:06:37

对于go语言在运行时的一些内存分配,想要详细的了解,我们会用到自带的runtime.MemStats,有很多具体的细节实现,而不是简单的只看任务管理器中的内存分配。

我们先来看下这个记录内存分配器的结构体

type MemStats struct {
	Alloc uint64		#堆空间分配的字节数
	TotalAlloc uint64		#服务运行一直累积的总分配的堆空间,释放也不减少
	Sys uint64		#操作系统获取的内存
	Lookups uint64		#运行时执行的指针查找数,用于调试
	Mallocs uint64		#服务malloc的次数
	Frees uint64		#释放堆对象字节数
	HeapAlloc uint64		#服务分配的堆内存字节数
	HeapSys uint64		#系统分配的堆内存字节数
	HeapIdle uint64		#申请但未分配的堆内存或者回收了的堆内存字节数
	HeapInuse uint64		#正在使用的堆内存字节数
	HeapReleased uint64	#返回给OS的堆内存,类似C/C++中的free
	HeapObjects uint64	#堆内存块申请的量
	StackInuse uint64		#正在使用的栈字节数
	StackSys uint64		#系统分配的作为运行栈的内存
	MSpanInuse uint64		#用于测试用的结构体使用的字节数
	MSpanSys uint64		#系统为测试用的结构体分配的字节数
	MCacheInuse uint64	#结构体申请的字节数,不被视为垃圾回收	
	MCacheSys uint64		#操作系统申请的堆空间用于mcache的量
	BuckHashSys uint64	#用于剖析桶散列表的堆空间
	GCSys uint64		#垃圾回收标记元信息使用的内存
	OtherSys uint64		#golang系统架构占用的额外空间
	NextGC uint64		#垃圾回收器检视的内存大小
	LastGC uint64		#垃圾回收器最后一次执行时间
	PauseTotalNs uint64	#垃圾回收或者其他信息收集导致服务暂停的次数
	PauseNs [256]uint64	#一个循环队列,记录最近垃圾回收系统中断的时间
	PauseEnd [256]uint64	# 一个循环队列,记录最近垃圾回收系统中断的时间开始点
	NumGC uint32		#垃圾回收完成的次数
	NumForcedGC uint32	#服务调用runtime.GC()强制使用垃圾回收的次数
	// GODEBUG=gctrace=1.
	GCCPUFraction float64	#垃圾回收占用服务CPU工作的时间总和
				#如果有100个goroutine,垃圾回收的时间为1s,总占用100s	
	EnableGC bool		#是否启用GC,如果启用,即便GOGC=off也是启用的
	DebugGC bool
	#内存分配器使用情况
	BySize [61]struct {
		Size uint32
		Mallocs uint64
		Frees uint64
	}
}

看个具体的示例:

package main

import (
	"fmt"
	"runtime"
	"time"
)

// 内存使用情况
func PrintMemUsage() {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)
	fmt.Printf("Alloc = %v MiB", bToMb(m.Alloc))
	fmt.Printf("\tTotalAlloc = %v MiB", bToMb(m.TotalAlloc))
	fmt.Printf("\tSys = %v MiB", bToMb(m.Sys))
	fmt.Printf("\tNumGC = %v\n", m.NumGC)
}

// 转国际标(兆字节)
func bToMb(b uint64) uint64 {
	return b / 1024 / 1024
}
func main() {
	var s []string

	for i := 0; i < 100000000; i++ {
		s = append(s, "你好,寅恪光潜!")
	}
	PrintMemUsage()

	for {
		//runtime.GC() //调用GC进行内存回收
		PrintMemUsage()
		fmt.Println(s[0])
		time.Sleep(time.Second * 1)
	}
}
/*
C:\Users\Tony>go run test.go
Alloc = 5625 MiB        TotalAlloc = 9192 MiB   Sys = 8066 MiB  NumGC = 25
Alloc = 4486 MiB        TotalAlloc = 9192 MiB   Sys = 8066 MiB  NumGC = 26
你好,寅恪光潜!
Alloc = 4486 MiB        TotalAlloc = 9192 MiB   Sys = 8066 MiB  NumGC = 26
你好,寅恪光潜!
Alloc = 4486 MiB        TotalAlloc = 9192 MiB   Sys = 8066 MiB  NumGC = 26
你好,寅恪光潜!
Alloc = 4486 MiB        TotalAlloc = 9192 MiB   Sys = 8066 MiB  NumGC = 26
...
*/

然后去掉runtime.GC()注释,启用内存回收,出现如下效果:

/*
C:\Users\Tony>go run test.go
Alloc = 4486 MiB        TotalAlloc = 9192 MiB   Sys = 7050 MiB  NumGC = 26
Alloc = 1838 MiB        TotalAlloc = 9192 MiB   Sys = 7050 MiB  NumGC = 27
你好,寅恪光潜!
Alloc = 1838 MiB        TotalAlloc = 9192 MiB   Sys = 7050 MiB  NumGC = 28
你好,寅恪光潜!
Alloc = 1838 MiB        TotalAlloc = 9192 MiB   Sys = 7050 MiB  NumGC = 29
你好,寅恪光潜!
Alloc = 1838 MiB        TotalAlloc = 9192 MiB   Sys = 7050 MiB  NumGC = 30
...
*/

上面选取了几个成员变量,可以看出这个运行时的内存查看还是挺方便详细的。

有时候需要做内存压力测试等,我们可能会用到消耗一定的内存,没有Linux纯环境,我在WSL中运行,如果你也是Windows系统想要熟悉Linux也可以查阅:Windows版的Linux子系统(WSL)安装

malloc_mb.c

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

#define UNIT (1024*1024)

int main(int argc, char *argv[])
{
    long long i = 0;
    int size = 0;

    if (argc != 2)
    {
        printf("请输入需要分配的内存值\n");
        return 1;
    }
    #unsigned long int strtoul(const char *nptr, char **endptr, int base);
    #unsigned long long int strtoull(const char *nptr, char **endptr,int base);
    size = strtoull(argv[1], NULL, 10);#字符串转换成数字,十进制
    if (size == 0)
    {
        printf("请输入大于0的内存值");
        return 1;
    }

    char *buff = (char *) malloc(size * UNIT);
    if (buff)
        printf("已分配%dMB\n", size);
    buff[0] = 1;

    for (i = 1; i < (size * UNIT); i++)
    {
        if (i%1024 == 0)
            buff[i] = buff[i-1]/8;
        else
            buff[i] = i/2;
    }
    pause();
}

编译成一个可执行文件:gcc malloc_mb.c -o malloc,目录下面将有个malloc文件,然后运行它:./malloc 1000
这样就会成功分配1000MB的内存!

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

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

相关文章

【新知实验室】腾讯云TRTC初体验

一、前言 今年腾讯云音视频发布了“三合一”的RT-ONE™网络。该网络整合了腾讯云实时通信网络&#xff08;TRTC&#xff09;、即时通信网络&#xff08;IM&#xff09;以及流媒体分发网络&#xff08;CDN&#xff09;三张网络&#xff0c;为业界最完整的音视频通信PaaS平台构建…

【App自动化测试】(八)三种等待方式——强制等待、隐式等待、显示等待

目录1. 为什么要添加等待&#xff1f;2. 三种等待方式3. 强制&#xff08;直接&#xff09;等待4. 隐式等待4.1 隐式等待说明4.2 隐式等待无法解决的问题5. 显式等待5.1 为什么要使用显示等待机制&#xff1f;5.1.1 Html文件加载顺序5.1.2 为什么要使用显示等待机制&#xff1f…

简化工作和生活的 7 个在线地图制作平台分享

地图制作是数据和艺术的结合&#xff0c;数据可以传达人们想要的信息&#xff0c;而艺术是传达信息的一种方式&#xff0c;两者的正确组合创造了完美的地图。 每个平台在功能和价格方面都是独一无二的&#xff0c;有人可能认为创建自定义地图需要高级制图知识或复杂的地理信息…

从react源码看hooks的原理

React暴露出来的部分Hooks //packages/react/src/React.js export {...useCallback,useContext,useEffect,useLayoutEffect,useMemo,useReducer,useRef,useState,... }功能描述 useState、useReducer: 状态值相关useEffect、useLayoutEffect: 生命周期相关useContext: 状态共…

Java多线程(一)——多线程的创建

多线程 在计算机中为了提高内存和资源的利用率&#xff0c;引入了并发编程的思想&#xff1b;多进程和多线程都能实现并发编程&#xff0c;但是多线程相对于多进程更“轻量”&#xff0c;&#xff08;多线程和多线程的关系和区别&#xff09;&#xff0c;所以这篇博客将着重讲…

CPU

文章目录CPU是什么CPU的构成1) 控制器2) 运算器3) 存储单元&#xff08;寄存器和高速缓存&#xff09;常见的CPU类型1) 单核 CPU2) 双核 CPU3) 四核 CPUCPU是什么 CPU 全称 Central Processing Unit&#xff0c;中文可译为中央处理器或者微处理器&#xff0c;或直接简称为处理…

挂脖式运动蓝牙耳机推荐,目前适合运动佩戴的五款耳机推荐

在科技的不断进步下&#xff0c;新型的骨传导耳机也是逐渐成为我们生活日常中的主流&#xff0c;其特殊的发声原理成为了我们喜爱的重点之一&#xff0c;也有些伙伴们还在边缘徘徊&#xff0c;想要入手骨传导耳机但又怕踩坑得不到好的体验&#xff0c;刚好小编在使用骨传导耳机…

【用户画像】应用场景

目前所做工作的主要业务场景&#xff1a;干货&#xff5c;一文从0到1掌握用户画像知识体系_腾讯新闻 广告联盟&#xff1f; 所谓广告联盟是什么呢&#xff1f;&#xff1f; 案例背景 某电商App的商品运营团队欲提升电子产品的老客复购率、新客下单率&#xff0c;于是选择了…

Tomcat常见问题解决方法总结,无法自动,无法访问,控制台乱码

Tomcat无法启动&#xff0c;无法访问 新下载的Tomcat&#xff0c;运行startup.bat后一闪而过&#xff0c;无法启动Tomcat服务。 可能会有这样的效果 可以在CMD窗口下进入Tomcat安装目录&#xff0c;运行startup可以看到报错信息。 可能有一下原因&#xff1a; 首先检查JAVA…

使用gitee部署静态网页

使用giteepages功能部署网页 需求 假如你辛辛苦苦写好了一个静态网页&#xff0c;很想要炫耀一下&#xff0c;让大家都可以通过公网访问看到我的网页。但是不想太麻烦&#xff0c;买服务器&#xff0c;安装软件&#xff0c;部署环境&#xff0c;配置域名&#xff0c;备案&…

通达信软件L2接口的委托队列有什么用?

如果我们开通了通达信Level 2接口&#xff0c;打开任意个股分时图&#xff0c;首先可以看到买一和卖一的部分委托&#xff08;如下图红框处&#xff09;。 点击【查看更多】&#xff0c;选择【委托队列】栏目&#xff0c;则可以看到完整的前50笔的委托买卖队列的数量。 而这些密…

【修电脑】VMware 从GHO文件备份恢复Win10/Win7系统

【修电脑】VMware 从GHO文件备份恢复Win10/Win7系统注意参考硬盘知识一、硬盘接口的分类二、硬盘的分类按照硬盘材质分为两大类按照接口类型区分boot启动知识Legacy BIOS引导uefi引导启动流程查看系统的引导启动方式1.VMware 新建win10 x64系统2.制作老毛桃U盘winpe3.VMware wi…

Linux C/C++ 学习笔记(七):DNS协议与请求

本文部分内容参考Linux C/C 开发&#xff08;学习笔记九 &#xff09;&#xff1a;DNS协议与请求的实现_菊头蝙蝠的博客-CSDN博客_struct dns 一、DNS的介绍 域名系统&#xff08;英文&#xff1a;Domain Name System&#xff0c;缩写&#xff1a;DNS&#xff09;的作用是将人…

佰维存储通过注册:拟募资8亿 国家集成电路基金是二股东

雷递网 雷建平 11月23日深圳佰维存储科技股份有限公司&#xff08;简称&#xff1a;“佰维存储”&#xff09;日前通过注册&#xff0c;准备在科创板上市。佰维存储计划募资8亿元&#xff0c;3亿元用于惠州佰维先进封测及存储器制造基地建设项目&#xff0c;2亿元用于先进存储器…

基于FME Desktop和FME Server的数据增量自动更新

一、自动更新的意义 自动更新使数据保持良好的现势性&#xff0c;具有良好现势性的数据可以准确反映最新情况&#xff0c;为领导者决策分析判断提供有力保障。 一年一度的国土变更调查就是国家为了及时全面查清我国土地利用状况&#xff0c;掌握详实准确的土地基础数据现势情…

项目分享:新年可以做的副业项目,红包封面制作

新的一年即将到来。今天想推荐一个非常暴力和稳定的项目&#xff0c;红包封面。这个项目在春节期间特别强大&#xff0c;因为新年包已经成为中国人的传统&#xff0c;从原来的纸包到现在的VX包已经成为一项必不可少的活动。因此&#xff0c;从需求的角度来看&#xff0c;这个项…

Linux 搭建本地镜像源(CentOS 离线 yum)

使用 RPM 包搭建本地镜像源 1. 下载所有源中的 RPM 包 yum -y install httpd yum-utils createrepo 创建 RPM 包的下载目录 mkdir /var/www/html/centos启动 httpd 服务 [rootlocalhost ~]# systemctl start httpd [rootlocalhost ~]# ss -antulp | grep :80 tcp LISTEN …

nerdctl 工具(用于 containerd 但兼容 docker CLI 习惯)

简介 nerdctl 是用于 containerd 并且 兼容 docker cli 习惯的管理工具&#xff0c;主要适用于刚从 docker 转到 containerd 的用户&#xff0c;操作 containerd 的命令行工具 ctr 和 crictl 不怎么好用&#xff0c;所以就有了 nerdctl。 要特别说明的是&#xff1a;nerdctl …

还在每天玩单调的控制台窗口?赶紧进来!!!用EasyX画出自己的优美窗口(万字教程,一文入门)

EasyX图形库教程 本文的封面第三章照片来自博客&#xff1a;爱心气球 文章目录EasyX图形库教程前言1.EasyX是什么&#xff1f;2.EasyX的安装开始教程1.基本概念1.1颜色1.2坐标2.创建窗口 -- 基本框架3.颜色设置3.1背景颜色3.2设置线条颜色3.3设置文本颜色3.4设置填充颜色4样式…

计算机毕业设计之java+ssm家校通网站

项目介绍 随着网络技术的飞速发展&#xff0c;网络已渗透到全人类的各个方面&#xff0c;深刻影响着我们的生活和工作方式。家校通网站给教育带来了更广阔的发展空间。家校通网站有对部分类似网站进行分析&#xff0c;找到规律和方法&#xff0c;吸取其特点&#xff0c;构思自…