成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux系列:如何用C#調(diào)用C方法造成內(nèi)存泄露

開(kāi)發(fā) 前端
在 windows 平臺(tái)上,我們常常在 C++ 代碼中用 extern "C"? 導(dǎo)出 C風(fēng)格 的函數(shù),然后在 C# 中用 DllImport 的方式引入,那在 Linux 上怎么玩的?

一、背景 

1. 講故事

今年準(zhǔn)備多寫(xiě)一點(diǎn) Linux平臺(tái)上的東西,這篇從 C# 調(diào)用 C 這個(gè)例子開(kāi)始。在 windows 平臺(tái)上,我們常常在 C++ 代碼中用 extern "C" 導(dǎo)出 C風(fēng)格 的函數(shù),然后在 C# 中用 DllImport 的方式引入,那在 Linux 上怎么玩的?畢竟這對(duì)研究 Linux 上的 C# 程序非托管內(nèi)存泄露有非常大的價(jià)值,接下來(lái)我們就來(lái)看下。

二、一個(gè)簡(jiǎn)單的非托管內(nèi)存泄露 

1. 構(gòu)建 so 文件

在 Windows 平臺(tái)上我們會(huì)通過(guò) MSVC 編譯器將 C代碼編譯出一個(gè)成品 .dll,在 Linux 上通常會(huì)借助 gcc 將 c 編譯成 .so 文件,這個(gè).so 全稱 Shared Object,為了方便講解,先上一段簡(jiǎn)單的代碼:

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#define BLOCK_SIZE (10 * 1024)              // 每個(gè)塊 10K
#define TOTAL_SIZE (1 * 1024 * 1024 * 1024) // 總計(jì) 1GB
#define BLOCKS (TOTAL_SIZE / BLOCK_SIZE)    // 計(jì)算需要的塊數(shù)

void heapmalloc()
{
    uint8_t *blocks[BLOCKS]; // 存儲(chǔ)每個(gè)塊的指針

    // 分配 1GB 內(nèi)存,分成多個(gè)小塊
    for (size_t i = 0; i < BLOCKS; i++)
    {
        blocks[i] = (uint8_t *)malloc(BLOCK_SIZE);
        if (blocks[i] == NULL)
        {
            printf("內(nèi)存分配失敗!\n");
            return;
        }

        // 確保每個(gè)塊都被實(shí)際占用
        memset(blocks[i], 20, BLOCK_SIZE);
    }

    printf("已經(jīng)分配 1GB 內(nèi)存在堆上!\n");
}

接下來(lái)使用 gcc 編譯,參考如下:

gcc -shared -o libmyleak.so -fPIC myleak.c
  • -shared: 編譯成共享庫(kù)
  • -fPIC:   指定共享庫(kù)可以在內(nèi)存任意位置被加載(地址無(wú)關(guān)性)

命令執(zhí)行完之后,就可以看到一個(gè) .so 文件了,截圖如下:

圖片圖片

最后可以用 nm 命令驗(yàn)證下 libmyleak.so 中是否有 Text 段下的 heapmalloc 導(dǎo)出函數(shù)。

root@ubuntu2404:/data2/c# nm libmyleak.so
0000000000004028 b completed.0
                 w __cxa_finalize@GLIBC_2.2.5
00000000000010c0 t deregister_tm_clones
0000000000001130 t __do_global_dtors_aux
0000000000003e00 d __do_global_dtors_aux_fini_array_entry
0000000000004020 d __dso_handle
0000000000003e08 d _DYNAMIC
000000000000125c t _fini
0000000000001170 t frame_dummy
0000000000003df8 d __frame_dummy_init_array_entry
00000000000020f8 r __FRAME_END__
0000000000003fe8 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
000000000000203c r __GNU_EH_FRAME_HDR
0000000000001179 T heapmalloc
0000000000001000 t _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 U malloc@GLIBC_2.2.5
                 U memset@GLIBC_2.2.5
                 U puts@GLIBC_2.2.5
00000000000010f0 t register_tm_clones
                 U __stack_chk_fail@GLIBC_2.4
0000000000004028 d __TMC_END__

2. C# 代碼調(diào)用

so構(gòu)建好了之后,后面就比較好說(shuō)了,使用 dotnet new console -n CSharpApplication --use-program-main true 新建一個(gè)CS項(xiàng)目。

root@ubuntu2404:/data2/csharp# dotnet new console -n CSharpApplication --use-program-main true
The template "Console App" was created successfully.

Processing post-creation actions...
Restoring /data2/csharp/CSharpApplication/CSharpApplication.csproj:
  Determining projects to restore...
  Restored /data2/csharp/CSharpApplication/CSharpApplication.csproj (in 1.7 sec).
Restore succeeded.

編譯下 C# 項(xiàng)目,然后將 libmyleak.so 放到 C#項(xiàng)目的 bin目錄,修改 C# 代碼如下:

using System.Runtime.InteropServices;

namespaceCSharpApplication;

classProgram
{
    [DllImport("libmylib.so", CallingConvention = CallingConvention.Cdecl)]
    public static extern void hello();

    static void Main(string[] args)
    {
        hello();
        Console.ReadLine();
    }
}

最后用 dotnet CSharpApplication.dll 運(yùn)行:

root@ubuntu2404:/data2/csharp/CSharpApplication/bin/Debug/net8.0# dotnet CSharpApplication.dll
已經(jīng)分配 1GB 內(nèi)存在堆上!

程序是跑起來(lái)了,那真的是吃了1G呢? 可以先用 htop 觀察程序,從截圖看沒(méi)毛病。

圖片圖片

那這 1G 真的在 heap 上嗎? 可以用 maps 觀察。

root@ubuntu2404:~# ps -ef | grep CSharp
root       10764   10730013:35 pts/21   00:00:00 dotnet CSharpApplication.dll
root       11049   11027013:41 pts/22   00:00:00 grep --color=auto CSharp

root@ubuntu2404:~# cat /proc/10764/maps
614e1f592000-614e1f598000 r--p 0000000008:021479867                    /usr/lib/dotnet/dotnet
614e1f598000-614e1f5a4000 r-xp 0000500008:021479867                    /usr/lib/dotnet/dotnet
614e1f5a4000-614e1f5a5000 r--p 0001000008:021479867                    /usr/lib/dotnet/dotnet
614e1f5a5000-614e1f5a6000 rw-p 0001000008:021479867                    /usr/lib/dotnet/dotnet
614e5b5d9000-614e9b8a8000 rw-p 0000000000:000                          [heap]
...


root@ubuntu2404:~# pmap 10764
10764:   dotnet CSharpApplication.dll
0000614e1f592000     24K r---- dotnet
0000614e1f598000     48K r-x-- dotnet
0000614e1f5a4000      4K r---- dotnet
0000614e1f5a5000      4K rw--- dotnet
0000614e5b5d9000 1051452K rw---   [ anon ]
...

根據(jù) linux 進(jìn)程的內(nèi)存布局,可執(zhí)行image之后是 heap 堆,可以看到 [heap] 約等于1G (614e9b8a8000 - 614e5b5d9000),即 pmap 中的 1051452K。

三、總結(jié) 

部署在 Linux上的.NET程序同樣存在 非托管內(nèi)存泄露的問(wèn)題,這篇文章的例子雖然很簡(jiǎn)單,希望能給大家?guī)?lái)一些思考和觀測(cè)途徑吧。

責(zé)任編輯:武曉燕 來(lái)源: 一線碼農(nóng)聊技術(shù)
相關(guān)推薦

2009-08-28 10:14:45

C#內(nèi)存泄露

2009-08-31 16:33:28

C#調(diào)用Dispose

2009-08-31 18:05:14

C#調(diào)用WalkTre

2009-09-01 11:04:59

C#調(diào)用擴(kuò)展方法

2009-08-03 12:57:27

C#調(diào)用DLL

2009-08-20 10:53:23

C#操作內(nèi)存

2009-08-24 15:58:00

Visual C#生成

2009-09-11 10:59:06

Effective C調(diào)用Dispose()

2009-08-26 16:58:12

調(diào)用C# Thread

2009-08-05 09:40:02

C#調(diào)用DLL函數(shù)

2009-09-02 10:49:46

C#調(diào)用析構(gòu)方法

2009-08-05 09:30:39

C#調(diào)用DLL函數(shù)

2011-04-08 09:52:44

C++C#DLL

2015-04-02 16:23:50

C++內(nèi)存泄露檢查

2009-08-17 16:18:47

C#調(diào)用CreateO

2025-05-08 03:33:00

Linuxperf.NET

2009-08-05 16:29:18

C#調(diào)用C++動(dòng)態(tài)鏈接

2009-08-17 15:34:58

C#創(chuàng)建XML

2009-08-20 16:07:39

C#和ADO.NET訪

2024-05-16 12:33:37

C#編程指針
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产超碰人人爽人人做人人爱 | 6080yy精品一区二区三区 | 在线视频成人 | 成年人视频在线免费观看 | 欧美三级网站 | 久久久国产一区二区三区 | 成人在线观看免费 | 亚洲第1页| 日日干夜夜草 | 成人欧美一区二区三区视频xxx | 午夜成人免费视频 | 欧美精品一区二区三区四区 在线 | 欧美不卡一区二区 | 天堂资源 | 欧美精品一区二区三区四区 在线 | 欧美精品一区二区在线观看 | 国产精品高清一区二区三区 | 日韩福利在线观看 | 久久久亚洲一区 | 日韩精品视频中文字幕 | 久久久久国产 | 成av在线| av片在线观看 | 国产色在线 | 综合久久综合久久 | 欧美日韩电影一区二区 | 日韩在线观看 | 国产成人精品一区二 | 久久久高清| 久久午夜视频 | 精品国产乱码久久久久久丨区2区 | 亚洲一卡二卡 | 一区二区播放 | 黄色片免费看 | 黄色片免费看视频 | 91福利网 | 久久亚洲精品国产精品紫薇 | 美女黄视频网站 | 亚洲精品乱码久久久久久按摩观 | 91精品久久久久久久99 | 中文字幕视频在线 |