Golang | статическая компиляция

Go

**Вопрос.** Почему для той же программы Hello World размер скомпилированной программы Go намного больше, чем скомпилированная программа C?

Поскольку C компилируется в виде динамической библиотеки, а go компилируется в виде статической компиляции, в результате получается больший размер скомпилированного бинарного файла;

В первые дни ресурсы памяти компьютера были очень ценными, поэтому была введена идея динамической загрузки и была создана библиотека динамической компоновки;

Сегодняшняя компьютерная память часто составляет десятки Г, и нет необходимости тратить много времени, чтобы сэкономить сотни К или 1 М памяти;

Go использует статическую компиляцию и не зависит от какой-либо библиотеки динамической компоновки, что позволяет избежать проблемы, связанной с различными зависимостями библиотеки динамической компоновки;

После компиляции, если платформа одна и та же (linux amd64), ее можно развернуть произвольно, вообще не учитывая проблему зависимости библиотеки ссылок;

Это преимущество.Некоторые люди жалуются, что размер исполняемого файла после компиляции слишком велик?

динамически подключаемая библиотека

При использовании библиотеки динамической ссылки иНе будет копировать весь код динамической библиотеки в сгенерированную программу, но для загрузки соответствующего кода во время работы программы, поэтому программа, использующая ту же динамическую библиотекумогу поделиться кодом, и при обновлении динамической библиотеки вам не нужно изменять код, который ее использует.

В то же время решается проблема хранения нескольких копий одного и того же машинного кода в физической памяти;

Хранить копию в физической памяти, чтобы процесс мог сопоставить этот код со своим собственным виртуальным адресным пространством;

И вы всегда можете обновить содержимое динамической библиотеки, без необходимости останавливать уже запущенную программу;

То есть, когда программа запускает свою собственную память, загруженной библиотекой динамической ссылки, когда его загружали в память, две памяти, которые не являются половиной десятью. Просто программа для сопоставления адреса DLL в собственное пространство памяти, поэтому ничего не позвоните;

Загрузка динамически подключаемых библиотек
  • Неявное связывание: требуется .lib .h .dll, и файл загружается в память при запуске программы; Комментарий #pragma(lib, "Dll.lib")
  • Явная ссылка: .h .dll требуется, загружается в режиме реального времени и загружается только тогда, когда это необходимо программе;
  • Таким образом, кажется, что плагин go неявно связан;
Как обновить работающую dll

Откройте DLL обнаружения потока, при обнаружении новой версии, удалите старую DLL, а затем загрузить новое;

Как происходит обновление плагинов?

p, err := plugin.Open("plugin1.so")
p, err := plugin.Open("plugin2.so")
定义一个全局变量,第二次open的时候覆盖第一次open就行了,下次调用就是新的函数了
当第二个so加载后,前面so的数据是没办法访问到,也就是说数据没法热更新(这时插件就不能用全局变量了)
//第一个插件不是还占着内存吗?等着被GC呗

//go的plugin只有打开模块和提取符号,没有关闭(卸载)
同一个so文件只能被打开一次
热更新只更新函数,不更新数据

//编译
go build -ldflags "-pluginpath=plugin1" -buildmode=plugin -o plugin1.so *.go
--ldflags里的-pluginpath的作用是: 每次编译的内部识别路径都是不同的, 避免重复加载的警告

Библиотека динамической компоновки под linux — это .so, а статическая библиотека — .a.

Библиотека динамической компоновки под окнами - это .dll

Следует отметить, что текущая динамическая библиотека (плагин) go поддерживает только Linux и не может использоваться под Windows.