Diferença entre bibliotecas estáticas e compartilhadas?

560

Qual é a diferença entre bibliotecas estáticas e compartilhadas?

Eu uso o Eclipse e existem vários tipos de projeto, incluindo bibliotecas estáticas e bibliotecas compartilhadas? Um tem uma vantagem sobre o outro?

Mohit Deshpande
fonte
4
A Wikipedia tem uma boa descrição da distinção entre bibliotecas estáticas, dinâmicas e compartilhadas.
11138 Adam Holmberg

Respostas:

745

Bibliotecas compartilhadas são arquivos .so (ou no Windows .dll ou no OS X .dylib). Todo o código relacionado à biblioteca está nesse arquivo e é referenciado por programas que o utilizam em tempo de execução. Um programa que usa uma biblioteca compartilhada faz apenas referência ao código que ele usa na biblioteca compartilhada.

Bibliotecas estáticas são arquivos .a (ou no Windows .lib). Todo o código relacionado à biblioteca está nesse arquivo e está diretamente vinculado ao programa no momento da compilação. Um programa que usa uma biblioteca estática obtém cópias do código que ele usa da biblioteca estática e faz parte do programa. [O Windows também possui arquivos .lib que são usados ​​para fazer referência a arquivos .dll, mas agem da mesma maneira que o primeiro].

Existem vantagens e desvantagens em cada método:

  • Bibliotecas compartilhadas reduzem a quantidade de código duplicado em cada programa que faz uso da biblioteca, mantendo os binários pequenos. Também permite substituir o objeto compartilhado por um que seja funcionalmente equivalente, mas pode ter benefícios adicionais de desempenho sem a necessidade de recompilar o programa que o utiliza. Porém, as bibliotecas compartilhadas terão um pequeno custo adicional para a execução das funções, bem como um custo de carregamento em tempo de execução, pois todos os símbolos da biblioteca precisam estar conectados às coisas que eles usam. Além disso, as bibliotecas compartilhadas podem ser carregadas em um aplicativo em tempo de execução, que é o mecanismo geral para implementar sistemas de plug-in binários.

  • Bibliotecas estáticas aumentam o tamanho geral do binário, mas isso significa que você não precisa carregar uma cópia da biblioteca que está sendo usada. Como o código é conectado no tempo de compilação, não há custos adicionais de carregamento em tempo de execução. O código está simplesmente lá.

Pessoalmente, prefiro bibliotecas compartilhadas, mas uso bibliotecas estáticas quando precisar garantir que o binário não tenha muitas dependências externas que possam ser difíceis de encontrar, como versões específicas da biblioteca padrão C ++ ou versões específicas da biblioteca Boost C ++.

Petesh
fonte
2
"substituir o objeto compartilhado por ... funcionalmente equivalente, mas pode [melhorar] o desempenho": especificamente, funcionalidade equivalente para o chamador no uso semântico da API (interface de programação de aplicativos: assinaturas e variáveis ​​de funções, incluindo tipos), mas no lado da implementação a funcionalidade pode diferir em mais do que perf .: por exemplo, a função sempre registra no arquivo -> também registra no servidor TCP: porta esperada em $ MY_APP_LOG_SERVER.
Tony Delroy
1
"[.sos incorrem em] um pequeno custo adicional para a execução das funções" - isso é possível (se os grupos de funções / pedidos tiverem sido otimizados para a localização do cache no link estático ou devido a esquisitices no SO / carregador / compilador / arquitetura como cross -segmento / multas perfurações de ponteiro grande), mas em muitas arquiteturas / configurações do compilador, o vinculador dinâmico corrige a chamada para criar exatamente os mesmos códigos de operação da máquina de chamada.
Tony Delroy
2
"Como o código é conectado no momento da compilação, não há custos adicionais de carregamento em tempo de execução. O código simplesmente está lá". - sim e não ... está tudo na imagem executável pronta para ser paginada se a execução exigir, mas - começando de uma situação em que seu programa não foi executado recentemente o suficiente para estar em cache - com bibliotecas compartilhadas é possível (às vezes provável ou certo) que o sistema operacional, um driver ou outro programa em execução já carregou a mesma biblioteca compartilhada que seu aplicativo deseja usar; nesse caso, ele pode estar em cache e o programa iniciar e executar mais rapidamente.
Tony Delroy
15
O que algumas pessoas não mencionaram é que, com as bibliotecas estáticas, o compilador sabe quais funções seu aplicativo precisa e pode otimizá-lo incluindo apenas essas funções. Isso pode reduzir enormemente o tamanho da biblioteca, especialmente se você usar apenas um subconjunto muito pequeno de uma biblioteca muito grande!
Jduncanator
1
Esta resposta poderia ser melhor organizada. Seria útil fazer listas de marcadores de prós / contras ou uma tabela para mostrar as diferenças em cada dimensão em que há uma diferença.
elefent
377

Uma biblioteca estática é como uma livraria e uma biblioteca compartilhada é como ... uma biblioteca. Com o primeiro, você obtém sua própria cópia do livro / função para levar para casa; com este último, você e todos os outros vão à biblioteca para usar o mesmo livro / função. Portanto, qualquer pessoa que queira usar a biblioteca (compartilhada) precisa saber onde ela está, porque você precisa "ir buscar" o livro / função. Com uma biblioteca estática, o livro / função é seu, e você o mantém em sua casa / programa e, depois de o ter, não se importa onde ou quando o adquiriu.

Paul Richter
fonte
70

Simplificado:

  • Ligação estática: um grande executável
  • Vinculação dinâmica: um pequeno executável mais um ou mais arquivos de biblioteca (arquivos .dll no Windows, .so no Linux ou .dylib no macOS)
StackedCrooked
fonte
1
Esta resposta é a melhor para mim porque é prática. Faz muito mais sentido do que uma metáfora que não fala sobre o que realmente está acontecendo no computador. Depois de saber que é isso que acontece, apenas conheço intuitivamente todas as outras implicações.
precisa saber é o seguinte
36

Para uma biblioteca estática, o código é extraído da biblioteca pelo vinculador e usado para criar o executável final no ponto em que você compila / constrói seu aplicativo. O executável final não tem dependências na biblioteca em tempo de execução

Para uma biblioteca compartilhada, o compilador / vinculador verifica se os nomes aos quais você vincula existem na biblioteca quando o aplicativo é criado, mas não move o código para o aplicativo. No tempo de execução, a biblioteca compartilhada deve estar disponível.

A linguagem de programação C em si não tem conceito de bibliotecas estáticas ou compartilhadas - elas são completamente um recurso de implementação.

Pessoalmente, prefiro usar bibliotecas estáticas, pois simplifica a distribuição de software. No entanto, essa é uma opinião sobre a qual muito sangue (figurativo) foi derramado no passado.


fonte
5
+1 para "A própria linguagem de programação C não tem conceito de bibliotecas estáticas ou compartilhadas - elas são completamente um recurso de implementação".
Tiger
1
Olá anon / @Tiger, por que você declarou "A própria linguagem de programação C não tem conceito de bibliotecas estáticas ou compartilhadas - elas são completamente um recurso de implementação". Você pode me explicar um pouco mais detalhadamente ou me indicar uma referência apropriada?
Sunil Shahu
@SunilShahu A forma como o programa é compilado e vinculado é específico para o compilador e o vinculador que você está usando, ou seja, a implementação específica da linguagem. As especificações de idioma geralmente não descrevem como os idiomas devem ser implementados ou construídos, apenas a funcionalidade, sintaxe, gramática etc.
JC Rocamonde
Os exemplos mais óbvios do @SunilShahu podem ser JavaScript, por exemplo, onde a especificação (EcmaScript) descreve os recursos da linguagem, mas são os diferentes fornecedores que fornecem os intérpretes JS (mecanismos do navegador ou Node.js, por exemplo). Por outro lado, a linguagem de programação Python possui várias implementações. O oficial é o CPython, mas existem outros escritos em outros idiomas.
JC Rocamonde 28/03
31

Bibliotecas estáticas são compiladas como parte de um aplicativo, enquanto bibliotecas compartilhadas não são. Quando você distribui um aplicativo que depende de bibliotecas compartilhadas, as bibliotecas, por exemplo. As DLLs no MS Windows precisam estar instaladas.

A vantagem das bibliotecas estáticas é que não há dependências necessárias para o usuário que está executando o aplicativo - por exemplo, eles não precisam atualizar sua DLL. A desvantagem é que seu aplicativo é maior em tamanho, porque você o envia com todas as bibliotecas necessárias.

Além de levar a aplicativos menores, as bibliotecas compartilhadas oferecem ao usuário a capacidade de usar sua própria versão, talvez melhor, das bibliotecas, em vez de confiar em uma que faz parte do aplicativo

Tarski
fonte
3
DLL inferno como tem sido conhecido
gheese
1
"Bibliotecas estáticas são compilados como parte de um aplicativo" ... bibliotecas estáticas são compilados como bibliotecas estáticas e ligados como parte de uma aplicação
idclev 463035818
19

A vantagem mais significativa das bibliotecas compartilhadas é que há apenas uma cópia do código carregado na memória, não importa quantos processos estejam usando a biblioteca. Para bibliotecas estáticas, cada processo obtém sua própria cópia do código. Isso pode levar a um desperdício significativo de memória.

OTOH, uma vantagem das bibliotecas estáticas é que tudo está incluído no aplicativo. Portanto, você não precisa se preocupar que o cliente tenha a biblioteca (e a versão) corretas disponíveis no sistema.

Jasmeet
fonte
1
a imagem executável é maior no disco, assim como na memória, ao usar bibliotecas estáticas.
precisa saber é o seguinte
Está correto, é isso que eu estava falando quando disse que tudo está incluído no seu aplicativo.
Jasmeet
Além disso, os .soarquivos nos sistemas * nix são uma biblioteca compartilhada (dinâmica).
snr
6

Além de todas as outras respostas, uma coisa ainda não mencionada é a dissociação:

Deixe-me falar sobre um código de produção do mundo real, com o qual tenho lidado:

Um software muito grande, composto por> 300 projetos (com visual studio), construído principalmente como lib estático e, finalmente, todos vinculados em um grande executável, você acaba com os seguintes problemas:

-O tempo de ligação é extremamente longo. Você pode acabar com mais de 15 minutos de link, digamos 10s de tempo de compilação. Algumas ferramentas estão de joelhos com um executável tão grande, como ferramentas de verificação de memória que devem instrumentar o código. Você pode cair em alcançar limites que eram vistos como tolos.

Mais problemático é o desacoplamento do seu software: neste exemplo do mundo real, os arquivos de cabeçalho de cada projeto eram acessíveis a partir de qualquer outro projeto. Como conseqüência, foi extremamente fácil para um desenvolvedor adicionar dependências; era apenas incluir o cabeçalho, porque o link no final permitirá que todos os símbolos encontrem símbolos. Ele acaba com dependências horríveis de ciclismo e bagunça completa.

Com a biblioteca compartilhada, é um trabalho extra porque o desenvolvedor deve editar o sistema de criação do projeto para adicionar a biblioteca dependente. Observei que o código da biblioteca compartilhada tende a oferecer uma API de código mais limpa.

madeira de linho
fonte
2
-------------------------------------------------------------------------
|  +-  |    Shared(dynamic)       |   Static Library (Linkages)         |
-------------------------------------------------------------------------
|Pros: | less memory use          |   an executable, using own libraries|
|      |                          |     ,coming with the program,       |
|      |                          |   doesn't need to worry about its   |
|      |                          |   compilebility subject to libraries|
-------------------------------------------------------------------------
|Cons: | implementations of       |   bigger memory uses                |
|      | libraries may be altered |                                     |
|      | subject to OS  and its   |                                     |
|      | version, which may affect|                                     |
|      | the compilebility and    |                                     |
|      | runnability of the code  |                                     |
-------------------------------------------------------------------------
snr
fonte