我的C ++对象文件太大了

时间:2021-12-31 16:48:37

I am working on a C++ program and the compiled object code from a single 1200-line file (which initializes a rather complex state machine) comes out to nearly a megabyte. What could be making the file so large? Is there a way I can find what takes space inside the object file?

我正在研究一个C ++程序,来自单个1200行文件(初始化一个相当复杂的状态机)的编译目标代码几乎达到了一兆字节。什么可以使文件这么大?有没有办法可以找到在目标文件中占用空间的东西?

5 个解决方案

#1


9  

There can be several reasons when object files are bigger than they have to be at minimum:

当目标文件大于它们必须至少时,可能有几个原因:

  • statically including dependent libraries
  • 静态地包括依赖库

  • building with debug information
  • 使用调试信息构建

  • building with profiling information
  • 建立分析信息

  • creating (extremely) complex data structures using templates (maybe recursive boost-structures)
  • 使用模板创建(极其)复杂的数据结构(可能是递归的boost结构)

  • not turning on optimizing flags while compiling (saves not that much and can cause difficulties if used too extremely)
  • 在编译时没有打开优化标志(保存不那么多,如果使用得太厉害会导致困难)

At first I suggest to check if you're building with debug information, this causes the most bloat in my experience.

首先,我建议检查您是否使用调试信息进行构建,这会导致我的体验中最臃肿。

#2


7  

(I'm assuming you've got optimisations and dead code stripping turned on).

(我假设你已经进行了优化并且打开了死代码剥离)。

Turn on your linker's "generate map file" option and examine the output.

打开链接器的“生成映射文件”选项并检查输出。

Common culprits are macros/templates that produce large amounts of code, and large global objects.

常见的罪魁祸首是产生大量代码和大型全局对象的宏/模板。

#3


5  

Possibly some template instantiations (especially the std::iostreams), and maybe extensive inlining (i.e. classes which are fully defined in a header). However, what's the problem with a 1-megabyte object file in the first place? During linking, it might very well result in a tiny binary. I got a project here with 20 MiB of object files which gets linked into a 700 KiB binary for example.

可能是一些模板实例化(特别是std :: iostreams),也许还有大量的内联(即在头文件中完全定义的类)。但是,首先是1兆字节的目标文件有什么问题?在链接期间,它可能会产生一个很小的二进制文件。我在这里得到了一个项目,其中包含20 MiB的目标文件,例如链接到700 KiB二进制文件。

Update: Could be also some large static array/object. Besides that, with MSVC++ and GCC, you can look at the generated assembly for a file, which can give you some hints (with GCC, it's g++ -S foo.cpp, for MSVC++, it's '/FAs'). Either you will see a lot of template instances, then these are the reason. If not, it's the object size of static objects.

更新:也可能是一些大的静态数组/对象。除此之外,使用MSVC ++和GCC,您可以查看生成的文件的程序集,它可以为您提供一些提示(使用GCC,它是g ++ -S foo.cpp,对于MSVC ++,它是'/ FAs')。要么你会看到很多模板实例,那么这就是原因。如果不是,那就是静态对象的对象大小。

#4


0  

Another possible reason is Link-Time Code Generation, a VC++ option. This moves the backend of the compiler into the linker. This allows for better optimizations, but the object file now has to contain all internal datastructures usually passed between front- and backend.

另一个可能的原因是链接时代码生成,一个VC ++选项。这会将编译器的后端移动到链接器中。这允许更好的优化,但是目标文件现在必须包含通常在前端和后端之间传递的所有内部数据结构。

#5


-3  

Here's a macro I use to see compile time values:

这是我用来查看编译时间值的宏:

template <size_t N> struct compile_time_number { private: typedef int check; };
#define compiler_check_number(N) ((compile_time_number< N >::check)0)

Then go happy at compile time to see what symbols are taking up space.

然后在编译时快乐,看看哪些符号占用空间。

Edit: Since no one seems to understand this, I'll clarify: the way to use this is to add compiler_check_number(sizeof(<insert struct or global variable here>)). The compiler will spit out the size of the variable or struct as a compile time error. Very rarely is code the reason for a huge object file.

编辑:由于似乎没有人理解这一点,我将澄清:使用它的方法是添加compiler_check_number(sizeof( ))。编译器会将变量或结构的大小吐出为编译时错误。很少有代码是巨大目标文件的原因。

I use this all the time to see how big things are without having to run a debugger.

我一直用这个来看看有多大的东西,而不必运行调试器。

#1


9  

There can be several reasons when object files are bigger than they have to be at minimum:

当目标文件大于它们必须至少时,可能有几个原因:

  • statically including dependent libraries
  • 静态地包括依赖库

  • building with debug information
  • 使用调试信息构建

  • building with profiling information
  • 建立分析信息

  • creating (extremely) complex data structures using templates (maybe recursive boost-structures)
  • 使用模板创建(极其)复杂的数据结构(可能是递归的boost结构)

  • not turning on optimizing flags while compiling (saves not that much and can cause difficulties if used too extremely)
  • 在编译时没有打开优化标志(保存不那么多,如果使用得太厉害会导致困难)

At first I suggest to check if you're building with debug information, this causes the most bloat in my experience.

首先,我建议检查您是否使用调试信息进行构建,这会导致我的体验中最臃肿。

#2


7  

(I'm assuming you've got optimisations and dead code stripping turned on).

(我假设你已经进行了优化并且打开了死代码剥离)。

Turn on your linker's "generate map file" option and examine the output.

打开链接器的“生成映射文件”选项并检查输出。

Common culprits are macros/templates that produce large amounts of code, and large global objects.

常见的罪魁祸首是产生大量代码和大型全局对象的宏/模板。

#3


5  

Possibly some template instantiations (especially the std::iostreams), and maybe extensive inlining (i.e. classes which are fully defined in a header). However, what's the problem with a 1-megabyte object file in the first place? During linking, it might very well result in a tiny binary. I got a project here with 20 MiB of object files which gets linked into a 700 KiB binary for example.

可能是一些模板实例化(特别是std :: iostreams),也许还有大量的内联(即在头文件中完全定义的类)。但是,首先是1兆字节的目标文件有什么问题?在链接期间,它可能会产生一个很小的二进制文件。我在这里得到了一个项目,其中包含20 MiB的目标文件,例如链接到700 KiB二进制文件。

Update: Could be also some large static array/object. Besides that, with MSVC++ and GCC, you can look at the generated assembly for a file, which can give you some hints (with GCC, it's g++ -S foo.cpp, for MSVC++, it's '/FAs'). Either you will see a lot of template instances, then these are the reason. If not, it's the object size of static objects.

更新:也可能是一些大的静态数组/对象。除此之外,使用MSVC ++和GCC,您可以查看生成的文件的程序集,它可以为您提供一些提示(使用GCC,它是g ++ -S foo.cpp,对于MSVC ++,它是'/ FAs')。要么你会看到很多模板实例,那么这就是原因。如果不是,那就是静态对象的对象大小。

#4


0  

Another possible reason is Link-Time Code Generation, a VC++ option. This moves the backend of the compiler into the linker. This allows for better optimizations, but the object file now has to contain all internal datastructures usually passed between front- and backend.

另一个可能的原因是链接时代码生成,一个VC ++选项。这会将编译器的后端移动到链接器中。这允许更好的优化,但是目标文件现在必须包含通常在前端和后端之间传递的所有内部数据结构。

#5


-3  

Here's a macro I use to see compile time values:

这是我用来查看编译时间值的宏:

template <size_t N> struct compile_time_number { private: typedef int check; };
#define compiler_check_number(N) ((compile_time_number< N >::check)0)

Then go happy at compile time to see what symbols are taking up space.

然后在编译时快乐,看看哪些符号占用空间。

Edit: Since no one seems to understand this, I'll clarify: the way to use this is to add compiler_check_number(sizeof(<insert struct or global variable here>)). The compiler will spit out the size of the variable or struct as a compile time error. Very rarely is code the reason for a huge object file.

编辑:由于似乎没有人理解这一点,我将澄清:使用它的方法是添加compiler_check_number(sizeof( ))。编译器会将变量或结构的大小吐出为编译时错误。很少有代码是巨大目标文件的原因。

I use this all the time to see how big things are without having to run a debugger.

我一直用这个来看看有多大的东西,而不必运行调试器。