.NET跨平台实践:Linux .Net Core自宿主应用程序瘦身记
一,.NET Core 自宿主应用程序个头很大
发布.NET Core应用程序有两个方式,一种是“便携式”,一种是“自宿主式”。便携式发布时,目标程序不带.net core运行环境,所以“个头”很小,可能只有几十K几百K字节,但是它需要用户的目标系统上安装.NET CORE 框架;自宿主式发布出来的程序,自带运行时和框架类库,自成一体,不需要客户机安装.NET CORE环境,部署简单方便。
看看一个简单的“Hello World!” 控制台程序有多大:

修改 csproj文件,添加目标系统:

用 dotnet publish -r:linux-x64 针对linux平台发布,得到目标文件(夹),现在看看大小:

这个Hello World 控制台程序的目标文件,总大小达到了62.2 MB!
二,为什么.net core自宿主程序这么大
原因有二,一是为了能在目标系统上 “独立” 运行,自宿主程序必须自带运行时,这无可厚非,二是不管是用 dotnet publish命令行发布还是用VS发布,它们都会不分青红皂白地把.net core类库整个发布到目标程序中,这正是使目标程序变大变肥的主要原因。
下面是发布后的部分文件列表,可以看出,很多的dll与这个hello world 程序毫无关系!

三,给 Linux .Net Core 自宿主应用程序瘦身
从前边的分析可以看出,自宿主应用程序之所有“肥大”,是因为有太多的无关的类库或Native so库造成的,只要清理掉它们,瘦身的目标就达到了。
1,将发布的程序全部上传到Linux系统的某个文件夹,然后运行 chmod +x coretest,给coretest赋与可执行权限。(我写的这个hello word程序名叫“coretest”)。

2,用 ./coretest 把程序运行起来:

不要按键,让程序不要退出。
3,查出这个进程的PID:
再加一个终端,用 ps -ef | grep coretest 查出这个进程的PID号

4,列出进程关联文件:
用 sudo lsof -p PID号,列出指定进程调用/引用的文件,从列表中找出属于这个core程序依赖的类库和core Navite函数库:
特点:路径都指向这个core程序所在的文件夹。
下图是列表的一部分:

从列表中,可以看出,本 coretest 程序,相关的文件有如下三类14个文件:
1)coretes加载程序和程序集:
coretest
coretest.dll
2)依赖的.net 框架程序集:
System.Runtime.dll
System.Console.dll
System.Threading.dll
System.Runtime.Extensions.dll
System.Collections.dll
3)运行时函数库:
libclrjit.so
libcoreclr.so
libhostpolicy.so
libhostfxr.so
System.Native.so
System.Globalization.Native.so
System.Private.CoreLib.dll
5,修改依赖文件 coretest.deps.json,对依赖行配置文件瘦身:
打开 coretest.deps.json文件,你会发现所有的依赖库都在其中,重要的是49行开始的“runtime.linux-x64.Microsoft.NETCore.App/2.0.0”的runtimes和native两个节点,共有173个依赖项,与我们测试出来的14个依赖,整整多了150多个,对于这个具体的程序而言,这150多个依赖都是多余的,这些多余的,都得删除!

删除后,deps.json一下子清爽了:

6,测试依赖配置文件是否正确:
再次用 ./coretest 运行本程序,检查依赖项是否正确。当按任意键退出程序时,出现了下边的错误。

原来,在Console.ReadKey返回时,会调用另一个dll,而之前用lsof时,没有程序没有执行到这一步,所以没有看到有这个依赖,这个依赖被误删了。所以,得重新加到deps.json文件中。

再次测试,程序已经完全正常。
7,根据瘦身后的依赖关系,删除无关文件:
要点,需要保留依赖列表文件coretest.deps.json和运行时配置文件coretest.runtimeconfig.json。
8,再次测试程序运行情况:
运行 ./coretest,发现出了一个问题:

差一个native 函数库,怎么办?简单,从windows发布目录中,上传到Linux的这个程序文件夹中。
再次运行,一帆风顺,瘦身工作正式完成!

现在看看这个程序,共计还有多少文件:

哈哈,现在只有19个文件!比如之前的近180个文件,这个”身“瘦得厉害吧,简直是一身清爽呀!
瘦身后,这个程序所有文件从62.2M变成了24.3m,打包压缩后,只有8.62M。
附记:
有的朋友可能会说,还是有点大呀,一个hello world就有19个文件24m大小,如果我司开发一个功能完整的商业应用会不会大得吓人?其实,我可以告诉你:
一,这19个文件已经具备了.net core的关键功能,你开发更大的商业应用,不外乎再多引用了几个dll而已,能再大多少!
二,这个程序是自带了运行环境的,它自成一体,独立运行,不需要麻烦你和你的客户或运维人员在linux上安装安装一大堆东西,配置一大堆东西!
三,正因为这个程序可以独立运行,那么,如果在Docker中,对docker镜像的体积影响可以忽略,比如那个动不动就数百M的镜像,你选什么?
.NET跨平台实践:Linux .Net Core自宿主应用程序瘦身记的更多相关文章
- 一个更好用的.NET Core程序瘦身器,减小程序尺寸到1/3
一.为什么要开发.NET Core程序瘦身器? .NET Core具有[剪裁未使用的代码]的功能,但是由于它是使用静态分析来实现的,因此它的剪裁效果并不是最优的.它有如下两个缺点: 不支持Window ...
- Linux .Net Core
Linux .Net Core自宿主应用程序瘦身记 一,.NET Core 自宿主应用程序个头有点大 发布.NET Core应用程序有两个方式,一种是“便携式”,一种是“自宿主式”.便携式发布时,目标 ...
- NET Core 2.0 微服务跨平台实践
NET Core 2.0 微服务跨平台实践 相关博文: Ubuntu 简单安装 Docker Mac OS.Ubuntu 安装及使用 Consul Consul 服务注册与服务发现 Fabio 安装和 ...
- .NET跨平台实践:.NetCore、.Net5/6 Linux守护进程设计
之前,我写过两篇关于用C#开发Linux守护进程的技术文章,分别是<.NET跨平台实践:用C#开发Linux守护进程>和<.NET跨平台实践:再谈用C#开发Linux守护进程 - 完 ...
- .net core 跨平台实践
本人采用Ubuntu 14.04 来实现.net core 的跨平台实践. 首先安装Ubuntu14.04系统.安装细节问百度. 1..net core console程序的跨平台 首先新建一个con ...
- .NET跨平台实践:再谈用C#开发Linux守护进程
Linux守护进程是Linux的后台服务进程,相当于Windows服务进程,对于为Linux开发服务程序的朋友来说,Linux守护进程相关技术是必不可少的,因为这个技术不仅仅是开发守护进程,还可以拓展 ...
- .NET跨平台实践:再谈用C#开发Linux守护进程 — 完整篇
Linux守护进程是Linux的后台服务进程,相当于Windows服务,对于为Linux开发服务程序的朋友来说,Linux守护进程相关技术是必不可少的,因为这个技术不仅仅是为了开发守护进程,还可以拓展 ...
- Ubuntu & Docker & Consul & Fabio & ASP.NET Core 2.0 微服务跨平台实践
相关博文: Ubuntu 简单安装 Docker Mac OS.Ubuntu 安装及使用 Consul Consul 服务注册与服务发现 Fabio 安装和简单使用 阅读目录: Docker 运行 C ...
- Docker & Consul & Fabio & ASP.NET Core 2.0 微服务跨平台实践
相关博文: Ubuntu 简单安装 Docker Mac OS.Ubuntu 安装及使用 Consul Consul 服务注册与服务发现 Fabio 安装和简单使用 阅读目录: Docker 运行 C ...
随机推荐
- ServerSocket简单例题
ServerSocket 简单例题: package com.kaige123.net; /* *凯哥 */ import java.io.FileInputStream; import java.i ...
- Codeforces_499C:Crazy Town(计算几何)
题目链接 给出点A(x1,y1),B(x2,y2),和n条直线(ai,bi,ci,aix + biy + ci = 0),求A到B穿过多少条直线 枚举每条直线判断A.B是否在该直线两侧即可 #incl ...
- 如何在Shell中快速切换目录
1.回到上一次进入的路经cd -2.回到Homecd ~3.自动补齐实例,cd /usr/src/redhat,可以用cd /u[TAB]s[TAB]r[TAB]4.!$ 表示上一个命令的最后一个参数 ...
- 用subline text写PHP后台服务器POST请求
1 运行XAMPP程序,看到Apache Web Server 是Running状态即可 2 打开Subline text ,新建一个PHP文件,选择保存路径:应用程序->XAMPP->h ...
- JMeter学习笔记-JForum环境搭建
一.准备环境 1. Java环境安装配置(JDK+JRE+环境变量) 2. Tomcat下载安装 下载地址: 安装教程:http://jingyan.baidu.com/article/870c6fc ...
- JavaWeb学习归档(一) - HTTP协议总结
版权声明:本文为博主原创文章,未经博主允许不得转载. 本文转载自我的个人博客:http://www.codingme.net/post/java-web-01 HTTP协议简介 超文本传输协议(HTT ...
- thinkphp实现无限级分类
普通的方法(采用for和foreach) //显示 foreach($data as $k=>$v){ //str_repeat()函数用于把字符串重复指定的次数 $data[$k]['titl ...
- 阿里消息队列中间件 RocketMQ源码解析:Message发送&接收
- zabbix_server----邮箱报警
zabbix邮件报警部署!!!!!!!!!!!!!!! Zabbix监控服务端.客户端都已经部署完成,被监控主机已经添加,Zabiix监控运行正常,通过查看Zabbix监控服务器,可以了解服务器的运行 ...
- NYOJ--139--我排第几个(康托展开)
我排第几个 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 现在有"abcdefghijkl"12个字符,将其所有的排列中按字典序排列,给出任意一 ...