Chương trình ngắn nhất liên tục phân bổ bộ nhớ


49

Viết chương trình chạy mãi mãi và phân bổ càng nhiều bộ nhớ trên heap càng lâu, ít nhất là cho đến khi bạn đạt đến giới hạn của hệ điều hành về số lượng bộ nhớ có thể được phân bổ.

Nhiều hạt nhân sẽ không thực sự dự trữ bộ nhớ mà bạn phân bổ cho đến khi bạn sử dụng nó cho một thứ gì đó, vì vậy nếu chương trình của bạn bằng C hoặc một số ngôn ngữ cấp thấp khác, bạn sẽ phải đảm bảo rằng bạn viết một cái gì đó cho mỗi trang. Nếu bạn đang sử dụng ngôn ngữ được dịch, có lẽ bạn sẽ không phải lo lắng về điều này.

Mã ngắn nhất sẽ thắng.


13
Là một ngăn xếp tràn là một giải pháp hợp lệ? Bộ nhớ có phải bị rò rỉ hoặc chỉ được phân bổ?
Thuật sĩ lúa mì

1
@WheatWizard Bộ nhớ không phải bị rò rỉ, nhưng nó phải được phân bổ nhanh hơn so với giải phóng.
tbodt

2
Một lần tôi muốn chương trình của mình tiêu thụ bộ nhớ vô hạn, tôi không thể làm được. (reduce conj [] (range))(Clojure) đạt tới 737mb, sau đó chỉ dừng phát triển. Idk làm thế nào nó không tiếp tục đi lên. Nó "nghĩ" tôi muốn in toàn bộ danh sách ở cuối, vì vậy nó không nên vứt đi bất cứ thứ gì. Rất bực bội.
Carcigenicate

14
Lưu ý đến bản thân: Lưu mã trước khi thử nghiệm. Giới thiệu rò rỉ mem có thể làm sập IDE ...
steenbergh

1
Tôi nghĩ bạn nên thêm một thử thách golf khác, tương tự nhưng riêng biệt với điều này, đòi hỏi chương trình tiêu thụ bộ nhớ nhanh hơn chức năng tuyến tính của thời gian. Đối với thử thách hiện tại , việc lặp lại mãi mãi và phân bổ một byte đơn sẽ ổn. Đối với thử thách mới của bạn , điều đó là không đủ, nhưng lặp đi lặp lại mãi mãi và nhân đôi số lượng bộ nhớ được sử dụng mỗi lần sẽ ổn.
BenGoldberg

Câu trả lời:


46

Funge-98 ( cfunge), 1 byte

9

Tôi đã đăng nó sớm hơn, nhưng đã quyết định thử nghiệm nó, và phải mất một thời gian để máy tính của tôi trở lại trạng thái có thể sử dụng được. cfungelưu trữ ngăn xếp Funge trên đống hệ điều hành (có thể kiểm chứng dễ dàng bằng cách chạy chương trình với giới hạn bộ nhớ nhỏ, điều mà tôi nên làm trước đó!), vì vậy, một ngăn xếp tăng trưởng vô hạn (như với chương trình này, chỉ cần đẩy 9liên tục; Các chương trình Funge bao bọc từ cuối dòng trở lại bắt đầu theo mặc định) sẽ phân bổ bộ nhớ mãi mãi. Chương trình này có khả năng cũng hoạt động trong một số triển khai Befunge-93.

Thú vị hơn:

"NULL #(4

Đây là ý tưởng đầu tiên của tôi và là một sự phân bổ vô hạn không dựa vào ngăn xếp Funge (mặc dù nó cũng làm nổ tung ngăn xếp Funge). Để bắt đầu, "lệnh sẽ đẩy một bản sao của phần còn lại của chương trình vào ngăn xếp (đó là một chuỗi và chương trình kết thúc tròn, do đó, trích dẫn đóng cũng đóng vai trò là trích dẫn mở). Sau đó, Nphản ánh (nó không có ý nghĩa theo mặc định), làm cho chương trình chạy ngược lại. Lần "nữa chạy lại và đẩy chương trình lên ngăn xếp - ngược lại lần này, với phần Ntrên cùng của ngăn xếp - sau đó chương trình kết thúc, tải một thư viện với tên 4 chữ cái ( 4(; NULLthư viện là một phần của cfungethư viện chuẩn). NULLđịnh nghĩa tất cả các chữ cái viết hoa để phản ánh, vì vậy Lphản ánh,#bỏ qua tải thư viện trên đường trở về, 4đẩy rác chúng ta không quan tâm đến ngăn xếp và toàn bộ chương trình lặp lại từ đầu. Cho rằng việc tải thư viện nhiều lần có hiệu lực và yêu cầu danh sách lệnh của thư viện được lưu trữ một lần cho mỗi bản sao của thư viện (điều này được ngụ ý bởi ngữ nghĩa của Funge-98), nó rò rỉ bộ nhớ thông qua lưu trữ không ngăn xếp (là một phương pháp thay thế để xác định "heap", liên quan đến ngôn ngữ hơn là hệ điều hành).


2
Tôi sẽ chấp nhận điều này ...
tbodt

Có cần thiết cho số là 9? Nó cũng sẽ hoạt động nếu nó là 5?
tbodt

Bất cứ điều gì đẩy vào ngăn xếp đều hoạt động (ngoại trừ có 0thể là việc triển khai Funge hoặc HĐH có thể tìm ra cách tối ưu hóa điều đó, với điều kiện bộ nhớ trong câu hỏi đã có sẵn số 0). Tôi chỉ chọn 9tùy tiện.

22
Không chấp nhận vì tôi muốn danh tiếng của mình vẫn là 666.
tbodt

7
@tbodt Không phải là lý do thực sự để không chấp nhận. Nếu bạn thích, tôi sẽ -1 câu hỏi của bạn. Sau đó, khi bạn chấp nhận, bạn sẽ vẫn còn 703 (lưu ý hiện tại bạn có 703 chứ không phải 666).
NoOneIsHãy là

30

Brainfuck, 5 byte

+[>+]

Điều này đòi hỏi một thông dịch viên không có giới hạn về độ dài của băng.


2
Tôi khá chắc chắn rằng nó + [> +] nếu không nó sẽ chỉ dừng lại ở lần lặp đầu tiên. ;)
Pâris Douady

Bạn nói đúng, xin lỗi vì lỗi đánh máy.
vsz

40
Một trong những lần hiếm hoi mà giải pháp
Brainfuck

@ Flp.Tkc Nhưng nó vẫn thua. Có lẽ nó sẽ thắng một ngày nào đó ...
NoOneIsHere 4/12/2016

6
@SeeOneRhino: Nó đã thắng một lần, đánh bại tất cả các ngôn ngữ chơi gôn> codegolf.stackexchange.com/questions/8915/ phỏng
vsz

22

Bash + coreutils, 5

hoặc là

Hồng ngọc, 5

`yes`

yestạo ra sản lượng vô tận. Đưa yesvào backticks cho shell để nắm bắt tất cả đầu ra và sau đó thực hiện đầu ra đó dưới dạng một lệnh. Bash sẽ tiếp tục phân bổ bộ nhớ cho chuỗi không có hồi kết này cho đến khi hết heap. Tất nhiên kết quả đầu ra sẽ là một lệnh không hợp lệ, nhưng chúng ta nên hết bộ nhớ trước khi điều đó xảy ra.

Cảm ơn @GB vì đã chỉ ra đây là một polyglot trong ruby.


7
Tôi đã định viết như vậy và gọi nó là chương trình Ruby.
GB

1
và perl, tôi nghĩ vậy.
abligh

18

Python, 16 byte

Giữ lồng acho đến khi đạt được một lỗi:

a=0
while 1:a=a,

Một vài lần lặp đầu tiên (như bộ dữ liệu) trông như thế này:

0
(0,)
((0,),)
(((0,),),)

Vân vân và vân vân.


18

> <> (Cá), 1 byte

0

Hãy thử nó ở đây!

0 thực sự có thể được thay thế cho bất kỳ số thập lục phân 1-f.

Giải trình

0trong> <> chỉ đơn giản là tạo ra một codebox 1x1 cho cá bơi vào. Nó liên tục thêm một 0ngăn xếp, bơi sang phải, vòng lặp ngược lại 0, thêm nó vào ngăn xếp một lần nữa. Điều này sẽ tiếp tục mãi mãi.


2
Bây giờ tôi đang tự hỏi có bao nhiêu ngôn ngữ 2 chiều khác hoạt động. Cuối cùng, hầu hết chúng đều dựa trên stack.

1
Hầu như hoạt động trong Cubix , nhưng nó đòi hỏi một .(hoặc bất kỳ char không phải khoảng trắng) nào để di chuyển 0vào dòng thực thi.
Sản xuất ETH

1
Hoạt động trong Ouroboros , nhưng không theo cùng một cách: Trình thông dịch cố gắng đọc 0000000...dưới dạng một số nguyên duy nhất và chuỗi mà nó xây dựng là thứ tiếp tục chiếm nhiều bộ nhớ hơn. Một chương trình hoạt động theo cách này sẽ làm a(đẩy 10 vô hạn).
DLosc

12

Java 101 byte

class A{public void finalize(){new A();new A();}public static void main(String[]a){for(new A();;);}}

Bắt chương trình chính trong một vòng lặp vô tận sau khi tạo và ném đi một đối tượng. Bộ sưu tập rác thực hiện công việc rò rỉ bằng cách tạo 2 đối tượng cho mỗi đối tượng bị xóa


tôi cảm thấy hơi ngớ ngẩn vì không đi với điều hiển nhiên bây giờ, haha. Tôi muốn nói rằng điều này thanh lịch hơn của tôi
Poke

1
vâng, mã của bạn đã nhớ tôi đến thực tế đó với phần cuối () @poke
masterX244

Tôi nghĩ bạn có thể làm cho nó ngắn hơn bằng cách thay thế chính bằng một trình khởi tạo tĩnh
tbodt

chỉ hoạt động tối đa java6 và tôi chỉ có các phiên bản cao hơn xung quanh
masterX244

2
haha sử dụng công cụ thu gom rác để gây rò rỉ! ý tưởng tuyệt vời :)
Mark K Cowan

12

Perl, 12 byte

{$"x=9;redo}

Trong perl, xtoán tử, với một chuỗi ở bên trái và một số ở bên phải, tạo ra một chuỗi lặp lại. Vì vậy, "abc" x 3đánh giá để "abcabcabc".

Các x=nhà điều hành đột biến đối số bên trái, thay thế nội dung của biến trên trái của nó với kết quả lặp lại nội dung của nó bao nhiêu lần tùy phía bên tay phải của nó chỉ ra.

Perl có một số lượng các biến được đặt tên kỳ lạ, một trong số đó là $", có giá trị ban đầu là một khoảng trắng.

Các redonhà điều hành nhảy đến đầu của bao vây {}.

Lần đầu tiên x=toán tử được thực hiện, nó thay đổi giá trị $"từ " ""đến " ", là 9 khoảng trắng.

Lần thứ hai x=toán tử được thực hiện, nó thay đổi giá trị $"thành " ", là 81 khoảng trắng.

Lần thứ ba, $"trở thành một chuỗi không gian dài 729 byte.

Tôi nghĩ bạn có thể thấy nơi này đang diễn ra :).


Bạn đánh bại tôi vào nó! Và của bạn ngắn hơn ba byte.
Gabriel Benamy

1
Đó chỉ là vấn đề tìm kiếm trang web này cho vòng lặp nhỏ nhất :). Ngoài ra, ban đầu tôi có $_.=7trong vòng lặp của mình, nhưng nhận ra rằng nếu tôi có thể sử dụng x=thì nó sẽ hết bộ nhớ nhanh hơn nhiều, và sau đó chạy perldoc perlvarđể chọn thứ gì đó phù hợp.
BenGoldberg

{$^O++;redo}ngắn hơn một byte khi ^Olà một chr(15)byte đơn . Mặc dù nó sẽ lãng phí bộ nhớ ở tốc độ chậm hơn NHIỀU - lặp lại 1000000000 trên Windows để lãng phí một byte. Sẽ hoạt động trên bất kỳ HĐH nào có tên bắt đầu bằng chữ Latinh.
Oleg V. Volkov

11

sed, 5 byte

Chơi gôn

H;G;D

Sử dụng (bất kỳ đầu vào sẽ làm)

sed 'H;G;D' <<<""

Giải thích

#Append a newline to the contents of the hold space, 
#and then append the contents of the pattern space to that of the hold space.
H

#Append a newline to the contents of the pattern space, 
#and then append the contents of the hold space to that of the pattern space. 
G

#Delete text in the pattern space up to the first newline, 
#and restart cycle with the resultant pattern space.
D

Ảnh chụp màn hình

nhập mô tả hình ảnh ở đây

Dùng thử trực tuyến!


2
Nói đúng ra đây là GNU sed (dấu chấm phẩy không phải là sed tiêu chuẩn) nhưng một dòng mới sẽ hoạt động tốt như dấu chấm phẩy.
R ..

10

Haskell, 23 19 byte

main=print$sum[0..]

In tổng của một danh sách vô hạn


Đây là một cách hay để thực thi đánh giá và nó cũng rất nhỏ gọn. +1
Trái cây Esolanging ngày 2/12/2016

một trình biên dịch rất có thể chạy cái này trong bộ nhớ O (1). Trong GHC, sumđược định nghĩa là foldl (+) 0, và những gì để ngăn chặn phân tích nghiêm ngặt để khởi động, để ngăn chặn vụ nổ? Bạn đã chạy nó được biên dịch với tối ưu hóa?
Will Ness

@WillNess Câu trả lời có thể là gì? sumsẽ không biết trước rằng danh sách này là vô hạn và printtheo tổng số thì nó phải được đánh giá trước. Và vâng, tôi đã biên dịch nó với tối ưu hóa
Angs

sẽ không có câu trả lời; nhưng phép tính sẽ chạy trong không gian O (1). Rất tiếc, vì mặc định Integer, các số không bị ràng buộc và bộ nhớ được lấy bởi kết quả hiện tại bignum , sẽ thực sự tăng lên.
Will Ness

1
chỉ cần làm rõ, điều tôi muốn nói là việc tính toán sum xs = foldl (+) 0 xscó thể chạy trong ngăn xếp không đổi, như bất kỳ vòng lặp bắt buộc nào. foldl' (+) 0 xschắc chắn sẽ Vì vậy, điều duy nhất phân bổ bộ nhớ cho chắc chắn, là kết quả tạm thời bignum.
Will Ness

9

C ++ (sử dụng trình biên dịch g ++), 27 23 15 byte

Cảm ơn Neop đã giúp tôi xóa 4 byte

Giải pháp này không thực sự rò rỉ bất kỳ bộ nhớ nào vì nó phân bổ mọi thứ trên ngăn xếp và do đó gây ra tràn ngăn xếp. Nó chỉ đơn giản là vô hạn đệ quy. Mỗi đệ quy làm cho một số bộ nhớ được phân bổ cho đến khi ngăn xếp tràn ra.

main(){main();}

Giải pháp thay thế

Giải pháp này thực sự rò rỉ bộ nhớ.

main(){for(;;new int);}

Sản lượng đầu ra

Đây là đầu ra Valgrind sau khi kết thúc chương trình vài giây vào thời gian chạy. Bạn có thể thấy rằng nó chắc chắn là bộ nhớ bị rò rỉ.

==2582== LEAK SUMMARY:
==2582==    definitely lost: 15,104,008 bytes in 3,776,002 blocks
==2582==    indirectly lost: 0 bytes in 0 blocks
==2582==      possibly lost: 16 bytes in 4 blocks
==2582==    still reachable: 4 bytes in 1 blocks
==2582==         suppressed: 0 bytes in 0 blocks

3
Tiêu đề là sai lệch; câu hỏi nói rằng "hãy viết một chương trình chạy mãi mãi và liên tục phân bổ bộ nhớ."
NobodyNada

Oh tôi đã không nhận ra bạn đã gửi câu trả lời khi tôi gửi của tôi.
Neop

1
@Neop Vâng, tôi không biết bạn có thể tham gia int cho đến khi tôi thấy bạn cảm ơn như vậy!
Thuật sĩ lúa mì

2
Không C++, chỉ là phương ngữ g ++ của nó: C ++ cấm gọi main; C ++ yêu cầu int main...khai báo. Nhưng giải pháp vẫn gọn gàng :-)
Martin Ba

1
Thật vậy, C ++ cấm gọi main.
R ..

9

JAVA, 81 79 78 byte

JAVA (HotSpot) 71 70 byte

Ngắn hơn các câu trả lời Java khác tại thời điểm tôi đăng (81, sau 79 byte):

class A{public static void main(String[]a){String x="1";for(;;)x+=x.intern();}}

Theo đề xuất của @Olivier Grégoire, một byte nữa có thể được lưu:

class A{public static void main(String[]a){for(String x="1";;)x+=x.intern();}}

Đặt x+=x.intern()làm tăng vòng lặp for sẽ không giúp được gì, vì dấu chấm phẩy vẫn được yêu cầu để kết thúc câu lệnh for.

Theo đề xuất của @ETHproductions, chỉ cần sử dụng x+=xcác tác phẩm:

class A{public static void main(String[]a){String x="1";for(;;)x+=x;}}

Điều này cũng có thể được hưởng lợi từ mẹo của @Olivier Grégoire:

class A{public static void main(String[]a){for(String x="1";;)x+=x;}}

Điều đáng tiếc duy nhất của tôi về điều đó là không đảm bảo phân bổ dữ liệu trên heap , vì một JVM hiệu quả có thể dễ dàng nhận ra rằng xkhông bao giờ thoát khỏi chức năng cục bộ. Việc sử dụng intern()sẽ tránh được mối lo ngại này vì cuối cùng các chuỗi được lưu trữ cuối cùng được lưu trữ trong một trường tĩnh. Tuy nhiên, HotSpot không tạo OutOfMemoryErrormã cho mã đó, vì vậy tôi đoán nó ổn.

Cập nhật: @Olivier Gregoire cũng chỉ ra rằng x+=xmã có thể chạy vào StringIndexOutOfBoundsExceptionthay vì OOMkhi có nhiều bộ nhớ. Điều này là do Java sử dụng loại 32 bit intđể lập chỉ mục các mảng (và Chuỗi chỉ là mảng của char). Điều này không ảnh hưởng đến x+=x.intern()giải pháp vì bộ nhớ cần thiết cho chuỗi sau là bậc hai theo chiều dài của chuỗi và do đó sẽ mở rộng theo thứ tự 2 ^ 62 byte được phân bổ.


Chào mừng đến với PPCG! Tôi không biết Java rất rõ; Điều gì sẽ xảy ra nếu bạn vừa mới làm x+=x;?
Sản xuất ETH

bạn có thể tắt dấu chấm phẩy bằng cách đặt x+=x.intern()dấu chấm phẩy cuối cùng của vòng lặp for
masterX244

Câu trả lời tốt đẹp. Tôi biết rằng phải có một cái gì đó với chuỗi interning nhưng tôi khá hài lòng với Unsafe và hoàn thành rằng tôi đã ngừng tìm kiếm, haha. Ban đầu câu hỏi này chỉ định "rò rỉ bộ nhớ", đó là lý do tại sao tôi không chỉ thực hiện một câu trả lời chuỗi chuỗi.
Chọc

Nếu câu trả lời của bạn phụ thuộc vào việc triển khai Java cụ thể và không nhất thiết phải có thể mang theo cho tất cả các triển khai Java, bạn có thể đặt thông tin trong tiêu đề (ví dụ # Java (HotSpot), 71 bytes). Theo cách đó, bạn không cần phải lo lắng về giải pháp có khả năng gian lận; các chương trình dành riêng cho việc triển khai là phổ biến không chỉ trong việc chơi golf, mà trong thế giới lập trình rộng lớn hơn, và miễn là bạn nhận thức được những gì bạn đang làm đôi khi có thể phù hợp hơn một chương trình di động, ví dụ như một tắt kịch bản.

1
humm ... x+=x;không làm cạn kiệt toàn bộ bộ nhớ. Với 64 GB, tôi nhận được StringIndexOutOfBoundsException, không phải OOM. Với .intern()tôi vẫn nhận được OOM.
Olivier Grégoire

8

Perl 6 , 13 byte

@= eager 0..*

Giải trình:

@ = lưu trữ kết quả vào một mảng không tên

eager làm cho danh sách sau đây háo hức

0 .. * phạm vi vô hạn bắt đầu từ 0


8

///, 7 byte

/a/aa/a

Liên tục thay thế abằng aa, quảng cáo.


12
*aad naauseum
timothymh

1
* ad nauseam=>aad naauseaam
Aaron

Thế còn //a/? Điều đó dường như mãi mãi thay thế `` (nothing) bởi a, nhưng không chắc điều này có được chỉ định chính xác không.
Cedric Reichenbach

6

Python 3, 16 byte

i=9
while 1:i*=i

Điều này xuất phát từ thực tế là không có giới hạn về kích thước số nguyên trong Python 3; thay vào đó, số nguyên có thể chiếm nhiều bộ nhớ mà hệ thống có thể xử lý (nếu có gì đó về sự hiểu biết của tôi về điều này là sai, hãy sửa lại cho tôi).


Tiêu đề ngụ ý rằng bộ nhớ nên bị rò rỉ. Nhưng điều này không thực sự rò rỉ bộ nhớ. Tác giả có lẽ nên làm rõ.
Thuật sĩ lúa mì

6

Rust, 46 byte

fn main(){loop{std::mem::forget(Box::new(1))}}

Nhận thấy một cái gì đó thú vị về chương trình Rust này, rò rỉ phân bổ heap cho đến khi hết bộ nhớ?

Đúng vậy, không có khối không an toàn. Rust đảm bảo an toàn bộ nhớ trong mã an toàn (không đọc dữ liệu chưa được khởi tạo, đọc sau miễn phí, miễn phí gấp đôi, v.v.), nhưng rò rỉ bộ nhớ được coi là hoàn toàn an toàn. Thậm chí còn có một hàm rõ ràng để làm cho trình biên dịch quên đi việc dọn dẹp RAII khỏi các biến phạm vi, mà tôi sử dụng ở đây.


6

TI-83 Hex hội, 7 byte

PROGRAM:M
:AsmPrgm
:EF6A4E
:C3959D
:C9

Tạo các ứng dụng vô thời hạn cho đến khi một ERR:MEMORYhệ điều hành bị ném. Chạy với Asm(prgmM). Tôi đếm từng cặp chữ số hex là một byte.


6

Python, 8 byte

2**9**99

Các OP đã cho phép technicality của một chương trình mà không kỹ thuật chạy "mãi mãi", nhưng bộ nhớ giao đất hơn bất kỳ máy tính có thể có thể xử lý. Đây không phải là một googolplex (nghĩa là 10**10**10011 byte), nhưng ngây thơ, cơ sở đăng nhập 2 của số này là

>>> 9**99.
2.9512665430652752e+94

tức là, 10 ^ 94 bit để thể hiện nó. WolframAlpha đặt nó lớn hơn 10 ^ 76 so với web sâu (hãy nhớ rằng có khoảng 10 ^ 80 nguyên tử trong vũ trụ ).

Tại sao 2 thay vì 9 bạn hỏi? Nó không tạo ra nhiều sự khác biệt (sử dụng 9 sẽ chỉ tăng số bit theo hệ số log2(9) = 3.2, thậm chí không thay đổi số mũ). Nhưng mặt khác, chương trình chạy nhanh hơn nhiều với 2, vì phép tính đơn giản hơn. Điều này có nghĩa là nó lấp đầy bộ nhớ ngay lập tức, trái ngược với phiên bản 9, mất nhiều thời gian hơn một chút do các tính toán cần thiết. Không cần thiết, nhưng tốt đẹp nếu bạn muốn "kiểm tra" điều này (điều mà tôi đã làm).


5

Thạch , 3 2 byte

-1 byte nhờ Dennis ( Wkết thúc tốt đẹp)

Một liên kết (tức là chức năng hoặc phương thức), cũng hoạt động như một chương trình đầy đủ, sẽ đệ quy kết hợp đầu vào của nó vào một danh sách.

Đầu vào bắt đầu bằng 0 nên đường chuyền đầu tiên tạo danh sách [0]
Đường chuyền thứ hai sau đó thực hiện [[0]]
đường chuyền thứ ba sau đó thực hiện điều này [[[0]]]
và cứ thế ...


3 byter trước đó, rò rỉ nhanh hơn nhiều:

;Ẇß

đệ quy nối tất cả các danh sách con liền kề không trống của đầu vào của nó với đầu vào của nó.
[0]-> [0,[0]]-> [0,[0],[0],[[0]],[0,[0]]]vân vân ...


Nếu tôi hiểu các quy tắc chính xác, ‘ßnên có rất nhiều.
Dennis

Điều đó có thực sự "phân bổ bộ nhớ liên tục" không (nghĩ về việc Python giữ phân bổ liên tục cho các số nguyên nhỏ).
Jonathan Allan

1
Đủ công bằng. Mặc dù vậy vẫn nên phù hợp với hóa đơn.
Dennis

5

Java 7, 106 byte

class A{public void finalize(){for(;;)Thread.yield();}public static void main(String[]a){for(;;)new A();}}

Ít chơi gôn

class A{
    @Override
    public void finalize(){
        for(;;) {
            Thread.yield();
        }
    }
    public static void main(String[]a){
        for(;;){
            new A();
        }
    }
}

Các finalizephương pháp được gọi là trên một đối tượng bằng cách thu gom rác khi thu gom rác thải xác định rằng không có nhiều tài liệu tham khảo cho các đối tượng. Tôi chỉ đơn giản là định nghĩa lại phương thức này để lặp lại mãi mãi để trình thu gom rác thực sự không bao giờ giải phóng bộ nhớ. Trong mainvòng lặp tôi tạo các đối tượng mới sẽ không bao giờ được dọn sạch nên cuối cùng điều này sẽ sử dụng hết bộ nhớ khả dụng.

Java 7 (thay thế thú vị), 216 byte

import sun.misc.*;class A{public static void main(String[]a)throws Exception{java.lang.reflect.Field f=Unsafe.class.getDeclaredField("theUnsafe");f.setAccessible(1>0);for(;;)((Unsafe)f.get(null)).allocateMemory(9);}}

Ít chơi gôn

import sun.misc.*;
class A{
    public static void main(String[]a)throws Exception{
        java.lang.reflect.Field f=Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe u = (Unsafe)f.get(null);
        for(;;) {
            u.allocateMemory(9);
        }
    }
}

Đây là một niềm vui nhiều hơn bất cứ điều gì khác. Câu trả lời này sử dụng Unsafethư viện Sun là API nội bộ không có giấy tờ. Bạn có thể cần thay đổi cài đặt trình biên dịch để cho phép các API bị hạn chế. Unsafe.allocateMemoryphân bổ một lượng byte được chỉ định (không có bất kỳ kiểm tra ranh giới nào) không nằm trong heap và không thuộc quản lý bộ thu gom rác của java để bộ nhớ này sẽ bám xung quanh cho đến khi bạn gọi Unsafe.freeMemoryhoặc cho đến khi jvm hết bộ nhớ.


1
Đã tự hỏi nếu tôi thấy Java ở đây.
Bạch tuộc ma thuật Urn

Không phải cái đầu tiên chỉ hoạt động nếu trình thu gom rác đang chạy trong một luồng riêng biệt?
tbodt

@tbodt có nhưng tôi không tin điều này không bao giờ xảy ra. Việc thu gom rác xảy ra trong một luồng daemon gọi là trình thu gom rác
Chọc

@Poke có đảm bảo không? nếu không câu trả lời vẫn ổn, nhưng bạn nên làm rõ rằng nó chỉ hoạt động nếu trình thu gom rác chạy trong luồng của chính nó
tbodt

@tbodt Tôi nghĩ vậy nhưng thật lòng tôi không chắc.
Chọc

5

Haskell, 24 byte

f x=f$x*x
main=pure$!f 9

Vấn đề chính trong Haskell là đánh bại sự lười biếng. maincần phải có một số IOloại, vì vậy chỉ cần gọi main=f 9sẽ không hoạt động. Sử dụng main=pure(f 9)thang máy loại f 9đến một IOloại. Tuy nhiên, sử dụng các cấu trúc như main=pure 9không làm gì cả, 9nó được trả về hoặc hiển thị ở đâu mà chỉ bị loại bỏ, do đó không cần phải đánh giá đối số pure, do đó main=pure(f 9)không gây ra bất kỳ bộ nhớ nào được phân bổ như fkhông được gọi. Để thực thi đánh giá, các $!nhà điều hành tồn tại. Nó chỉ đơn giản là áp dụng một hàm cho một đối số nhưng đánh giá đối số trước. Vì vậy, sử dụng main=pure$!f 9đánh giá fvà do đó liên tục phân bổ bộ nhớ nhiều hơn.


Khi được biên dịch, bộ thực thi phát hiện vòng lặp và ngắt thực thi
Angs

@Angs Tôi đã biên dịch với ghc trên windows và nó vẫn vui vẻ phân bổ bộ nhớ ... Tôi đã dừng nó ở mức 3GB.
Laikoni

Sử dụng f x=f xcông trình quá, phải không? (
Byte2

@wchargein Tôi không nghĩ vậy, f x=f xtạo ra một vòng lặp vô hạn, nhưng không phân bổ bộ nhớ mới.
Laikoni

Đẹp, làm cho bộ nhớ nổ tung bởi các tính toán bignum! f!x=x*f(x*x)nên làm cho nó tối ưu hóa bằng chứng.
Will Ness

5

dc, 7 byte

[ddx]dx

[ddx]đẩy một chuỗi chứa "ddx" vào ngăn xếp. dxsao chép nó sau đó thực thi nó dưới dạng mã (để lại một bản sao trên ngăn xếp). Khi được thực thi, nó tạo hai bản sao sau đó thực thi một bản sao, để lại một bản sao trên ngăn xếp mỗi lần.


Đợi đã, vậy cái này sẽ phân bổ theo cấp số nhân bộ nhớ nếu nó có thể chạy song song?
HyperNeutrino

5

Haskell (sử dụng ghc 8.0.1), 11 byte

m@main=m>>m

Đệ quy không đuôi. maingọi chính nó và sau đó chính nó một lần nữa.


Điều này phân bổ trên heap hoặc stack? (Tôi cũng có thể tin; nó cũng có thể phụ thuộc vào trình biên dịch Haskell đang sử dụng.)

1
@ ais523: tùy. Haskell không có ngăn xếp cuộc gọi . Hệ thống thời gian chạy RTS có một vùng bộ nhớ để khớp mẫu, còn được gọi là "ngăn xếp". Ngăn xếp này được phân bổ trên đống. Thành thật mà nói, tôi không biết chuyện gì đang xảy ra ở đây, vì chương trình thất bại với Stack space overflow: current size 33624 bytes.33k có vẻ khá thấp so với 6G của tổng bộ nhớ mà HĐH đang báo cáo.
nimi

1
@ ais523: dường như có một lỗi trong thông tin bộ nhớ của thông báo lỗi ghc, vì vậy thật khó để biết chính xác điều gì xảy ra.
nimi

Được biên dịch trên GHC 7.10.3 trên Ubuntu, việc này dường như chiếm một lượng bộ nhớ không đổi ngay cả khi tối ưu hóa bị vô hiệu hóa
Angs

@Angs: hmm, tôi sử dụng ghc 8.0.1 trên MacOS. Tôi sẽ chỉnh sửa nó trong.
nimi

5

C (linux), 23 byte

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

sbrk()tăng đỉnh của phân đoạn dữ liệu theo số byte đã cho, do đó tăng hiệu quả lượng bộ nhớ được phân bổ cho chương trình - ít nhất là như đã báo cáo trong VIRTtrường topđầu ra. Điều này chỉ hoạt động trên Linux - việc triển khai macOS rõ ràng là một mô phỏng chỉ cho phép phân bổ tối đa 4 MB.


Vì vậy, một câu trả lời chung chung hơn một chút:

C, 25 byte

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

Tôi đã xem nó trên macOS Activity Monitor. Nó đã đi hết khoảng 48GB, rồi cuối cùng quá trình nhận được tín hiệu SIGKILL. FWIW macbook pro của tôi có 16GB. Hầu hết các bộ nhớ được sử dụng đã được báo cáo là nén.

Lưu ý rằng câu hỏi có hiệu quả đòi hỏi mỗi phân bổ phải được viết, điều này không xảy ra rõ ràng ở đây. Tuy nhiên, điều quan trọng cần lưu ý là đối với mỗi malloc(9)cuộc gọi, không chỉ có 9 byte người dùng yêu cầu được phân bổ. Đối với mỗi khối được phân bổ, sẽ có một tiêu đề malloc cũng được phân bổ từ đâu đó trên heap, điều này nhất thiết phải được ghi bởi các malloc()bên trong.


Với malloc, bạn không trực tiếp ghi vào bộ nhớ vì malloc không khởi tạo bất cứ thứ gì. Bộ nhớ chỉ được phân bổ vì malloc cần một số bộ nhớ trong để quản lý bộ nhớ. Vì vậy, câu trả lời không thực sự chuẩn nhưng tôi đoán nó vẫn hoạt động ở mọi nơi.
Antzi

@Antzi Vâng. Tuy nhiên, tôi nghĩ rằng điều này vẫn hoạt động mặc dù mặc dù bộ nhớ người dùng có thể không thực sự được phân bổ trước khi nó được ghi vào, mỗi malloc()khối ed vẫn phải có không gian được phân bổ thực sự của riêng nó. Điều này hoạt động trên macOS và Ubuntu.
Chấn thương kỹ thuật số

Điều kiện trong câu hỏi của mỗi trang được viết là khá vô nghĩa; ngay cả khi bạn muốn giả sử một hệ điều hành không thực hiện kế toán cam kết phù hợp, bất kể chi tiết triển khai có nhất thiết phải có một lượng kế toán khác không cần thiết cho mỗi phân bổ. Cho dù nó có liền kề với phân bổ (khiến các trang bị chạm) hay không, cuối cùng nó sẽ tiêu tốn một lượng bộ nhớ tùy ý để ghi sổ với dữ liệu khác (nhất thiết).
R ..

Bạn có thể có được nó nhỏ hơn một byte main(){main(malloc(9));}, nhưng để không bị tràn, nó cần tối ưu hóa cuộc gọi đuôi và gcc dường như không muốn làm điều đó vào main...
R ..

Nếu bạn thay thế malloc (9) bằng calloc (9,9) thì sẽ có đủ bộ nhớ được phân bổ cho 9 trường hợp của khối 9 byte (do đó, giữa 81 và 144 byte, tùy thuộc vào căn chỉnh. Tuy nhiên, và quan trọng hơn là calloc ( ) sẽ không lấp đầy khối bộ nhớ, buộc HĐH bên dưới phải phân bổ dung lượng lưu trữ cho nó.
CSM

5

Perl, 4 byte

do$0

Thực thi chính nó, trong trình thông dịch hiện tại. Khi kết thúc, thực thi trở lại tập lệnh gọi, yêu cầu ngăn xếp cuộc gọi.


Đẹp và ngắn, mặc dù nó không lãng phí bộ nhớ nhanh như của tôi.
BenGoldberg

4

Vợt, 13 byte

(let l()(l)1)

Tôi không hoàn toàn chắc chắn nếu câu trả lời của tôi rơi vào câu hỏi này. Xin vui lòng cho tôi biết nếu tôi nên loại bỏ câu trả lời này.


Bạn có thể giải thích làm thế nào nó hoạt động?
tbodt

1
oh, vậy nó được định nghĩa llà một hàm không đệ quy đuôi. Tôi muốn nói rằng nó có giá trị.
tbodt

@tbodt vâng, bạn đúng về tiền
Winny

4

JavaScript 22 21 17 16 15 byte

for(a=0;;)a=[a]

Đã lưu 4 byte bằng cách gói danh sách trong một danh sách khác như trong câu trả lời Jelly của @Jonathan Allan.

Đã lưu 1 byte nhờ @ETH sản phẩm

Giải pháp thay thế 15 Byte (chỉ hoạt động với các cuộc gọi đuôi thích hợp)

f=a=>f([a]);f()

1
Trong ví dụ thứ 2 của bạn với ES6, bạn không thể làm gì f=_=>f();f()? 12 byte
bị cắn

@bitten Tôi không chắc. Nếu nó được tính để thổi ngăn xếp cuộc gọi, thì cuộc gọi không có đuôi đó sẽ là cách tốt nhất. Với TCO, tôi không nghĩ sẽ có bất kỳ bộ nhớ nào bị rò rỉ, phải không?
Lmis

cả hai thổi chồng cuộc gọi cho tôi . Tôi không thực sự quen thuộc với các cuộc gọi đuôi vì vậy tôi không thể nhận xét về điều đó.
cắn

1
ah tôi hiểu rồi, tôi không chắc là bạn đã bị rò rỉ bộ nhớ như thế nào
cắn

1
Bạn có thể loại bỏ a=0. Lặp lại đầu tiên sẽ dẫn đếna=[undefined]
Florent

4

Ruby, 11 byte

loop{$*<<9}

Tiếp tục đẩy 9lên $*, đó là một mảng ban đầu giữ các đối số dòng lệnh cho quy trình Ruby.


4

05AB1E , 2 byte

[A

Hãy thử trực tuyến! Sẽ chỉ tiếp tục đẩy abcdefghijklmnopqrstuvwyxzlên ngăn xếp mãi mãi.

Tất cả các giải pháp 2 byte có thể:

[  # Infinite loop.
 A # Push alphabet.
 0 # Push 0.
 1 # Push 1.
 2 # Push 2.
 3 # Push 3.
 4 # Push 4.
 5 # Push 5.
 6 # Push 6.
 7 # Push 7.
 8 # Push 8.
 9 # Push 9.
 T # Push 10.
 X # Push 1.
 Y # Push 2.
 ® # Push -1.
 ¶ # Push \n.
 º # Push len(stack) > 0, so 0 once then 1 for eternity.
 ð # Push a space.
 õ # Push an empty string.
 ¾ # Push 0.
 ¯ # Push [].
 M # Push -inf.
 ) # Wrap current stack in an array.

Rất kỹ lưỡng! Đẹp.
timothymh

3

Python, 35 byte

def f(a=[]):a.append(a)
while 1:f()

a không bao giờ được phát hành và chỉ lớn hơn cho đến khi bạn đạt được MemoryError

Bạn có thể xem thực thi trên Python Tutor .


1
Bạn có thể làm được a+=a,không
Cyoce

Không cần chức năng, đây là golf của tôi
FlipTack

@ Flp.Tkc câu hỏi đã được thay đổi sau khi tôi viết câu trả lời này, tôi sẽ làm những gì bạn đã làm (+ - vài ký tự) nếu nó ở định dạng hiện tại.
Noelkd

3

TI-BASIC, 8

:Lbl A
:While 1
:Goto A

(tất cả các mã thông báo 1 byte và hai dòng mới)

Điều này liên tục rò rỉ bộ nhớ vì luồng điều khiển có cấu trúc như Whiledự đoán được đóng bởi một Endvà đẩy một cái gì đó trên ngăn xếp (không phải ngăn xếp hệ điều hành, một ngăn xếp riêng trong bộ nhớ heap) để theo dõi điều đó. Nhưng ở đây chúng tôi đang sử dụng Gotođể rời khỏi vòng lặp (vì vậy không có gì Endđược thực thi để loại bỏ thứ đó khỏi ngăn xếp), cái Whileđược nhìn thấy lại, thứ được đẩy lại, v.v. Vì vậy, nó chỉ tiếp tục đẩy chúng cho đến khi bạn nhận đượcERR:MEMORY

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.