Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6873481
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T04:04:27+00:00 2026-05-27T04:04:27+00:00

Sometimes it’s handy to mock up something with a little C program that uses

  • 0

Sometimes it’s handy to mock up something with a little C program that uses a big chunk of static memory. I noticed after changing to Fedora 15 the program took a long time to
compile. We’re talking 30s vs. 0.1s. Even more weird was that ld (the
linker) was maxing out the CPU and slowly started eating all available
memory. After some fiddling I managed
to find a correlation between this new problem and the size of my swap
file. Here’s an example program for the purposes of this discussion:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define M 1000000
#define GIANT_SIZE (200*M)

size_t g_arr[GIANT_SIZE];

int main( int argc, char **argv){   
    int i;
    for(i = 0; i<10; i++){
        printf("This should be zero: %d\n",g_arr[i]);
    }
    exit(1);
}

This program has a giant array which has a declared size of about
200*8MB = 1.6GB of static memory. Compiling this program takes an
inordinate amount of time:

[me@bleh]$ time gcc HugeTest.c 

real    0m12.954s
user    0m6.995s
sys 0m3.890s

[me@bleh]$

13s For a ~13 line C program!? That’s not right. The key number is the
size of the static memory space. As soon as it is larger than the
total swap space, it starts to compile quickly again. For example, I
have 5.3GB of swap space, so changing GIANT_SIZE to (1000*M) gives the
following time:

[me@bleh]$ time gcc HugeTest.c 

real    0m0.087s
user    0m0.026s
sys 0m0.027s

Ah, that’s more like it! To further convince myself (and yourself, if
you’re trying this at home) that swap space was indeed the magic
number, I tried changing the available swap space to a truly massive
19GB and trying to compile the (1000*M) version again:

[me@bleh]$ ls -ali /extraswap 
5986 -rw-r--r-- 1 root root 14680064000 Jul 26 15:01 /extraswap
[me@bleh]$ sudo swapon /extraswap 
[me@bleh]$ time gcc HugeTest.c 

real    4m28.089s
user    0m0.016s
sys 0m0.010s

It didn’t even complete after 4.5 minutes!

Clearly the linker is doing something wrong here, but I don’t know how
to work around this other than rewriting the program or messing around
with swap space. I’d love to know if there’s a solution, or if I’ve
stumbled upon some arcane bug.

By the way, the programs all compile and run correctly, independent of all the swap business.

For reference, here is some possibly relevant information:

[]$ ulimit -a

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 27027
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

[]$ uname -r

2.6.40.6-0.fc15.x86_64

[]$ ld --version

GNU ld version 2.21.51.0.6-6.fc15 20110118
Copyright 2011 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

[]$ gcc --version

gcc (GCC) 4.6.1 20110908 (Red Hat 4.6.1-9)
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[]$ cat /proc/meminfo 
MemTotal:        3478272 kB
MemFree:         1749388 kB
Buffers:           16680 kB
Cached:           212028 kB
SwapCached:       368056 kB
Active:           489688 kB
Inactive:         942820 kB
Active(anon):     401340 kB
Inactive(anon):   803436 kB
Active(file):      88348 kB
Inactive(file):   139384 kB
Unevictable:          32 kB
Mlocked:              32 kB
SwapTotal:      19906552 kB
SwapFree:       17505120 kB
Dirty:               172 kB
Writeback:             0 kB
AnonPages:        914972 kB
Mapped:            60916 kB
Shmem:              1008 kB
Slab:              55248 kB
SReclaimable:      26720 kB
SUnreclaim:        28528 kB
KernelStack:        3608 kB
PageTables:        63344 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    21645688 kB
Committed_AS:   11208980 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      139336 kB
VmallocChunk:   34359520516 kB
HardwareCorrupted:     0 kB
AnonHugePages:    151552 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:      730752 kB
DirectMap2M:     2807808 kB

TL;DR: When the (large) static memory of a c program is slightly less than the available swap space, the linker takes forever to link the program. However, it’s quite snappy when the static space is slightly larger than the available swap space. What’s up with that!?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T04:04:28+00:00Added an answer on May 27, 2026 at 4:04 am

    I am able to reproduce this on an Ubuntu 10.10 system (GNU ld (GNU Binutils for Ubuntu) 2.20.51-system.20100908), and I think I have your answer. First, some methodology.

    After confirming this happens to me in a small VM (512MB ram, 2GB swap), from here I decided the easiest thing to do would be to strace gcc and see what exactly was going on when everything went to hell:

    ~# strace -f gcc swap.c
    

    It illuminated the following:

    vfork()                                 = 3589
    [pid  3589] execve("/usr/lib/gcc/x86_64-linux-gnu/4.4.5/collect2", ["/usr/lib/gcc/x86_64-linux-gnu/4."..., "--build-id", "--eh-frame-hdr", "-m", "elf_x86_64", "--hash-style=gnu", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-o", "swap", "-z", "relro", "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., ...], [/* 26 vars */]) = 0
    
    ...
    
    [pid  3589] vfork()                     = 3590
    
    ...
    
    [pid  3590] execve("/usr/bin/ld", ["/usr/bin/ld", "--build-id", "--eh-frame-hdr", "-m", "elf_x86_64", "--hash-style=gnu", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-o", "swap", "-z", "relro", "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., ...], [/* 27 vars */]) = 0     
    
    ...
    
    [pid  3590] lseek(13, 4096, SEEK_SET)   = 4096
    [pid  3590] read(13, ".\4@\0\0\0\0\0>\4@\0\0\0\0\0N\4@\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
    [pid  3590] mmap(NULL, 1600004096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1771931000
    <system comes to screeching halt>
    

    It would appear that, as we might have suspected, it looks like ld is actually trying to anonymously mmap the entire static memory space of this array (or possibly the entire program, it’s hard to tell since the rest of the program is so small, it might all fit in that extra 4096).

    So that’s all well and good, but why does it work when we exceed the available swap on the system? Let’s turn swapoff and run strace -f again…

    [pid  3618] lseek(13, 4096, SEEK_SET)   = 4096
    [pid  3618] read(13, ".\4@\0\0\0\0\0>\4@\0\0\0\0\0N\4@\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
    [pid  3618] mmap(NULL, 1600004096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
    [pid  3618] brk(0x60638000)             = 0x1046000
    [pid  3618] mmap(NULL, 1600135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
    [pid  3618] mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7fd011864000
    
    ...
    

    Unsurprisingly, ld seems to do the same thing it tried last time, to mmap the entire space. but the system is no longer able to do that, it fails! ld tries again, and it fails again, then ld does something unexpected… it moves on with less memory.

    Weird, I guess we’d better have a look at the ld code then. Drat, it doesn’t do an explicit mmap. This must be coming from inside of a plain old malloc. We’ll have to build ld with some debug symbols to track this down. Unfortunately, when I built bin-utils 2.21.1 the problem went away. Perhap it’s been fixed in newer versions of bin-utils?

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Sometimes, when I look through my header files I'd like to add something little
sometimes i see that certain projects write something to the output during compilation. how
Sometimes I have to work on code that moves the computer clock forward. In
Sometimes I have come across this issue that whenever I change the order of
Sometimes I get errors that I suspect are the result of my Django app
Sometimes I start a MATLAB script and realize too late that it is going
Sometimes, for certain things like writing a line to a console, feels like something
Sometimes I've seen a solution that includes up to three .csproj files for each
Sometimes this program errors with a segmentation fault. What is a segmentation fault? Why
Sometimes it happens that for some reason the process of copying many files (i.e.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.