StackOverflowError그 원인 은 무엇 이며 어떻게 처리해야합니까?
기억 누수
예외 처리
메모리 부족
스택 오버플로
공유 이 질문을 개선 따르다
생성 07 jan. 192019-01-07 18:58:22 s.
댄 페어 라이 즐
2,1022골드 배지 2 개25은색 배지 25 개29청동 휘장 29 개 생성 18 a.
Ziggy
19.9k2323 개의 골드 배지7171 개의 은색 배지9797 개의 브론즈 배지
Java의 스택 크기가 작습니다. 그리고 많은 재귀 호출과 같은 경우이 문제에 직면합니다. 루프로 코드를 재 설계 할 수 있습니다. 일반적인 디자인 패턴은 다음 URL에서 찾을 수 있습니다. jndanial.com/73 – JNDanial Sep 19 '18 at 4:01
명확하지 않은 방법 중 하나는 new Object() {{getClass().newInstance();}};정적 컨텍스트 (예 : main메서드)에 줄 을 추가하는 것 입니다. 인스턴스 컨텍스트에서 작동하지 않습니다 (발생 만 InstantiationException). – John McClane '18 년 12 월 4 일 2:03
의견을 추가하다
15 개의 답변
422
매개 변수와 지역 변수는 스택에 할당됩니다 (참조 유형을 사용하면 객체는 힙 에 있고 스택의 변수는 힙의 해당 객체를 참조합니다). 스택은 일반적으로 주소 공간 의 상단에 있으며, 사용 되면 주소 공간 의 하단 (즉, 0 쪽)으로 향합니다.
프로세스에는 프로세스 의 하단에 있는 힙 도 있습니다 . 메모리를 할당하면이 힙은 주소 공간의 상단으로 갈수록 커질 수 있습니다. 보시다시피 힙 이 스택과 "충돌" 할 가능성이 있습니다 (지각판과 비슷합니다 !!!).
스택 오버플로의 일반적인 원인은 잘못된 재귀 호출 입니다. 일반적으로 이는 재귀 함수에 올바른 종료 조건이 없어서 자신을 영원히 호출 할 때 발생합니다. 또는 종료 조건이 양호한 경우이를 충족하기 전에 너무 많은 재귀 호출을 요구하여 발생할 수 있습니다.
그러나 GUI 프로그래밍을 사용하면 간접 재귀 를 생성 할 수 있습니다 . 예를 들어 앱에서 페인트 메시지를 처리 할 수 있으며이를 처리하는 동안 시스템이 다른 페인트 메시지를 보내도록하는 함수를 호출 할 수 있습니다. 여기서 당신은 명시 적으로 자신을 부르지 않았지만 OS / VM이 당신을 위해 그것을했습니다.
이를 처리하려면 코드를 검토해야합니다. 자신을 호출하는 함수가 있으면 종료 조건이 있는지 확인하십시오. 그렇다면 함수를 호출 할 때 인수 중 하나 이상을 수정했는지 확인하십시오. 그렇지 않으면 재귀 적으로 호출되는 함수에 대한 가시적 인 변경이없고 종료 조건이 쓸모가 없습니다. 또한 유효한 종료 조건에 도달하기 전에 스택 공간에 메모리가 부족할 수 있으므로 메서드가 더 많은 재귀 호출이 필요한 입력 값을 처리 할 수 있는지 확인하십시오.
명백한 재귀 함수가없는 경우 간접적으로 함수를 호출하는 라이브러리 함수를 호출하고 있는지 확인하십시오 (위의 암시 적 사례처럼).
공유 이 답변을 개선 따르다
생성 16 jul.
톰
13.2k1414 개의 골드 배지4141 개의 은색 배지4747 개의 브론즈 배지
생성 18 a.
션
54.7k10골드 배지 10 개8484 개의 은색 배지125125 개의 브론즈 배지
삼
원본 포스터 : 이거 대단해. 그래서 재귀는 항상 스택 오버플로를 담당합니까? 아니면 다른 것들도 그들에게 책임을 질 수 있습니까? 불행히도 나는 라이브러리를 사용하고 있지만 내가 이해하는 것은 아닙니다. – Ziggy 2008-10-18 09:04
5
Ha ha ha, 여기 있습니다 : while (points <100) {addMouseListeners (); moveball (); checkforcollision (); pause (speed);} 와우, 마우스 청취자들로 가득 차게 될 것이라는 사실을 깨닫지 못해 절망감을 느끼나요 ... 감사합니다! – Ziggy 2008 년 10 월 18 일 11:26
6
아니요, 스택 오버플로는 en.wikipedia.org/wiki/Stack_overflow 에서 Wikipedia 기사를 찾아 보면 스택에 할당하기에는 너무 큰 변수로 인해 발생할 수도 있습니다 . – JB King 2008 년 11 월 4 일 23:30
10
스택 오버플로 오류를 "처리"하는 것은 거의 불가능하다는 점을 지적해야합니다 . 대부분의 환경에서 오류를 처리하려면 스택에서 코드를 실행해야합니다. 스택 공간이 더 이상 없으면 어렵습니다. – Hot Licks 2014 년 1 월 25 일 14:09
5
@JB King : 원시 유형과 참조 만 스택에 유지되는 Java에는 실제로 적용되지 않습니다. 모든 큰 물건 (배열과 객체)은 힙에 있습니다. - jcsahnwaldt 분석 재개 모니카 2시 25분에서 1월 23일 '15
보여 4 개 의견
117
이를 설명하기 위해 먼저 지역 변수와 객체가 저장되는 방식을 이해하겠습니다 .
지역 변수는 스택 에 저장됩니다 . 여기에 이미지 설명 입력
이미지를 보면 작동 방식을 이해할 수있을 것입니다.
Java 애플리케이션에서 함수 호출을 호출하면 스택 프레임이 호출 스택에 할당됩니다. 스택 프레임에는 호출 된 메서드의 매개 변수, 로컬 매개 변수 및 메서드의 반환 주소가 포함됩니다. 반환 주소는 호출 된 메서드가 반환 된 후 프로그램 실행이 계속되는 실행 지점을 나타냅니다. 새 스택 프레임을위한 공간이 없으면 StackOverflowErrorJVM (Java Virtual Machine)에서을 처리합니다.
Java 애플리케이션의 스택을 소진시킬 수있는 가장 일반적인 경우는 재귀입니다. 재귀에서 메서드는 실행 중에 자신을 호출합니다. 재귀는 강력한 범용 프로그래밍 기술로 간주되지만주의해서 사용해야합니다 StackOverflowError.
던지기의 예 StackOverflowError는 다음과 같습니다.
StackOverflowErrorExample.java :
public class StackOverflowErrorExample {
public static void recursivePrint(int num) {
System.out.println("Number: " + num);
if (num == 0)
return;
else
recursivePrint(++num);
}
public static void main(String[] args) {
StackOverflowErrorExample.recursivePrint(1);
}
}
스 니펫 확장
이 예제에서 우리 recursivePrint는 정수를 인쇄 한 다음 다음 연속 정수를 인수로 사용하여 자신을 호출 하는 재귀 메서드를 정의합니다 . 재귀는 0매개 변수로 전달할 때까지 끝납니다 . 그러나이 예에서는 1과 증가하는 팔로워의 매개 변수를 전달하므로 결과적으로 재귀가 종료되지 않습니다.
-Xss1M스레드 스택의 크기를 1MB로 지정 하는 플래그를 사용하는 샘플 실행 은 다음과 같습니다.
Number: 1
Number: 2
Number: 3
...
Number: 6262
Number: 6263
Number: 6264
Number: 6265
Number: 6266
Exception in thread "main" java.lang.StackOverflowError
at java.io.PrintStream.write(PrintStream.java:480)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
at java.io.PrintStream.write(PrintStream.java:527)
at java.io.PrintStream.print(PrintStream.java:669)
at java.io.PrintStream.println(PrintStream.java:806)
at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:4)
at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
...
JVM의 초기 구성에 따라 결과가 다를 수 있지만 결국은 StackOverflowErrorthrow됩니다. 이 예는주의해서 구현하지 않으면 재귀가 어떻게 문제를 일으킬 수 있는지 보여주는 아주 좋은 예입니다.
StackOverflowError를 처리하는 방법
가장 간단한 해결책은 스택 추적을주의 깊게 검사하고 반복되는 행 번호 패턴을 감지하는 것입니다. 이 줄 번호는 재귀 적으로 호출되는 코드를 나타냅니다. 이러한 줄을 감지하면 코드를주의 깊게 검사하고 재귀가 종료되지 않는 이유를 이해해야합니다.
재귀가 올바르게 구현되었는지 확인한 경우 더 많은 호출을 허용하기 위해 스택의 크기를 늘릴 수 있습니다. 설치된 JVM (Java Virtual Machine)에 따라 기본 스레드 스택 크기는 512KB 또는 1MB와 같을 수 있습니다 . -Xss플래그를 사용하여 스레드 스택 크기를 늘릴 수 있습니다 . 이 플래그는 프로젝트의 구성 또는 명령 줄을 통해 지정할 수 있습니다. -Xss인수 형식 은 다음과 같습니다. -Xss
공유 이 답변을 개선 따르다
생성 25 5 월 25 일 15:32:14
생성 26 mar.
바룬
5,19915골드 배지 15 개65은색 배지 65 개105브론즈 배지 105 개
-Xss 인수는 새로운 스레드에 적용됩니다 창을 사용하는 경우 일부 자바 버전에서 버그가 보인다 - goerlibe을 9시 17분에서 6월 8일 '17
의견을 추가하다
66
다음과 같은 기능이있는 경우 :
int foo()
{
// more stuff
foo();
}
그런 다음 foo ()는 계속해서 자신을 호출하여 점점 더 깊어지고, 어떤 함수에 있는지 추적하는 데 사용되는 공간이 가득 차면 스택 오버플로 오류가 발생합니다.
공유 이 답변을 개선 따르다
생성 18 a.
Khoth
12.5k2골드 배지 2 개2626 개의 은색 배지2727 개의 브론즈 배지
12
잘못된. 귀하의 함수는 꼬리 재귀입니다. 대부분의 컴파일 된 언어에는 꼬리 재귀 최적화가 있습니다. 즉, 재귀가 단순한 루프로 줄어들고 일부 시스템에서이 코드 조각으로 스택 오버플로가 발생하지 않습니다. – Cheery 2008 년 10 월 18 일 09:29
어떤 비 기능적 언어가 꼬리 재귀를 지원합니까? – horseyguy 2009-08-10 19:52
@banister와 자바 스크립트의 일부 구현 - Pacerier 1월 29일 '12 14시 7분에서
@horseyguy Scala는 Tail 재귀를 지원합니다. – Ajit K'sagar '17 11 월 19 일 18:50
이것은 스택 오버플로를 생성 할 수있는 것의 본질을 포착합니다. 좋은. – Pixel '18 .01.18 22:35
의견을 추가하다
24
스택 오버플로는 정확히 스택 오버플로를 의미합니다. 일반적으로 프로그램에는 로컬 범위 변수와 루틴 실행이 끝날 때 반환 할 주소를 포함하는 하나의 스택이 있습니다. 이 스택은 메모리 어딘가에 고정 된 메모리 범위 인 경향이 있으므로 값을 포함 할 수있는 양이 제한됩니다.
스택이 비어 있으면 팝할 수없고, 그렇게하면 스택 언더 플로 오류가 발생합니다.
스택이 가득 차면 푸시 할 수없고, 그렇게하면 스택 오버플로 오류가 발생합니다.
따라서 스택에 너무 많이 할당하면 스택 오버플로가 나타납니다. 예를 들어, 언급 된 재귀에서.
일부 구현은 일부 형태의 재귀를 최적화합니다. 특히 꼬리 재귀. 테일 재귀 루틴은 루틴이 수행하는 최종 작업으로 재귀 호출이 나타나는 루틴의 한 형태입니다. 이러한 일상적인 호출은 단순히 점프로 축소됩니다.
일부 구현은 재귀를 위해 자체 스택을 구현하기 때문에 시스템 메모리가 부족할 때까지 재귀를 계속할 수 있습니다.
시도 할 수있는 가장 쉬운 방법은 가능한 경우 스택 크기를 늘리는 것입니다. 그래도 그렇게 할 수 없다면 두 번째로 좋은 방법은 분명히 스택 오버플로를 일으키는 원인이 있는지 확인하는 것입니다. 통화 전후에 무언가를 일상으로 인쇄하여 시도하십시오. 이것은 실패한 루틴을 찾는 데 도움이됩니다.
공유 이 답변을 개선 따르다
생성 18 a.
기분 좋은
21k1313 개의 골드 배지55은색 배지 55 개80브론즈 배지 80 개
5
스택 언더 플로 와 같은 것이 있습니까? – Pacerier '12 .01.29.14 : 09
6
스택 언더 플로는 어셈블리에서 가능하지만 (푸시 한 것보다 더 많이 터짐) 컴파일 된 언어에서는 거의 불가능합니다. 확실하지 않습니다. 음수 크기를 "지원"하는 C의 alloca () 구현을 찾을 수있을 것입니다. – Score_Under 2013 년 2 월 9 일 0:14
2
스택 오버플로는 정확히 스택 오버플로를 의미합니다. 일반적으로 프로그램에는 로컬 범위 변수를 포함하는 하나의 스택이 있습니다.-> 아니요, 모든 스레드에는 로컬 변수를 포함하는 모든 메서드 호출에 대한 스택 프레임을 포함하는 자체 스택이 있습니다. – Koray Tugay May 2 '15 at 21:58
의견을 추가하다
9
스택 오버플로는 일반적으로 함수 호출을 너무 깊게 중첩하거나 (특히 재귀를 사용하는 경우, 즉 자기 자신을 호출하는 함수) 스택에 많은 양의 메모리를 할당하여 힙을 사용하는 것이 더 적절할 때 호출됩니다.
공유 이 답변을 개선 따르다
생성 18 a.
그렉
288k5151 개의 금 휘장351은색 배지 351 개325브론즈 배지 325 개
1
죄송합니다. Java 태그를 보지 못했습니다 – Greg Oct 18 '08 08:23
또한 여기 원본 포스터에서 : 중첩 기능이 너무 깊게 무엇입니까? 다른 기능? 그리고 : 스택이나 힙에 메모리를 할당하는 방법은 무엇입니까? – Ziggy 2008-10-18 08:26
@Ziggy : 예, 한 함수가 또 다른 함수를 호출하는 등 다른 함수를 호출하는 경우 여러 수준 후에 프로그램에 스택 오버플로가 발생합니다. [계속] – Chris Jester-Young 2008 년 10 월 18 일 9:25
[... 계속] Java에서는 스택에서 메모리를 직접 할당 할 수 없습니다 (반면 C에서는 할 수 있으며이 경우 감시 할 수 있음). 따라서 그 원인이 아닐 가능성이 높습니다. Java에서 모든 직접 할당은 "new"를 사용하여 힙에서 가져옵니다. – Chris Jester-Young 2008 년 10 월 18 일 9:26
@ ChrisJester-Young 메서드에 100 개의 지역 변수가 있으면 모든 것이 예외없이 스택에 올라간다는 것이 사실입니까? – Pacerier '12 .01.29.14 : 08
보여 6 개 댓글 더
7
말씀하신 것처럼 코드를 보여 주셔야합니다. :-)
스택 오버플로 오류는 일반적으로 함수가 중첩을 너무 깊게 호출 할 때 발생합니다. 이것이 어떻게 발생하는지에 대한 몇 가지 예 는 Stack Overflow Code Golf 스레드를 참조하십시오 (그 질문의 경우 답변은 의도적으로 스택 오버플로를 유발합니다).
공유 이 답변을 개선 따르다
생성 23 may.
커뮤니티 ♦
11은색 배지 1 개
생성 18 a.
크리스 제스터 영
20 만4444 개의 골드 배지364은색 배지 364 개410브론즈 배지 410 개
1
코드를 추가하고 싶지만 스택 오버플로의 원인을 모르기 때문에 어떤 코드를 추가해야할지 모르겠습니다. 모든 코드를 추가하면 절름발이 겠죠? – Ziggy 2008 년 10 월 18 일 8:27
프로젝트가 오픈 소스입니까? 그렇다면 Sourceforge 또는 github 계정을 만들고 거기에 모든 코드를 업로드하십시오. :-) – Chris Jester-Young 2008 년 10 월 18 일 9:37
이것은 좋은 생각처럼 들리지만 나는 내가 무엇을 업로드해야할지조차 알지 못하는 멍청한 사람입니다. 마찬가지로, 내가 확장하는 클래스 등을 가져 오는 라이브러리는 모두 나에게 알려지지 않았습니다. 오 맨 : 나쁜 시간. – Ziggy 2008-10-18 09:49
의견을 추가하다
5
스택 오버플로의 가장 일반적인 원인은 지나치게 깊거나 무한한 재귀 입니다. 이것이 문제인 경우 Java Recursion에 대한이 자습서 가 문제를 이해하는 데 도움이 될 수 있습니다.
공유 이 답변을 개선 따르다
생성 18 a.
Splattne
98.3 천50골드 배지 50 개200은색 배지 200 개246브론즈 배지 246 개
의견을 추가하다
5
StackOverflowErrorOutOfMemoryError힙 과 마찬가지로 스택에 있습니다.
제한되지 않은 재귀 호출로 인해 스택 공간이 사용됩니다.
다음 예제는 다음을 생성합니다 StackOverflowError.
class StackOverflowDemo
{
public static void unboundedRecursiveCall() {
unboundedRecursiveCall();
}
public static void main(String[] args)
{
unboundedRecursiveCall();
}
}
StackOverflowError 불완전한 메모리 내 호출의 총 합계 (바이트)가 스택 크기 (바이트)를 초과하지 않도록 재귀 호출이 제한되는 경우 피할 수 있습니다.
공유 이 답변을 개선 따르다
생성 16 may.
8bitjunkie
10.9k99 개의 골드 배지4848 개의 은색 배지64청동 휘장 64 개
생성 17 jul.
비 크람
3,5848골드 배지 8 개32은색 배지 32 개5656 개의 브론즈 배지
의견을 추가하다
삼
다음은 단일 연결 목록을 뒤집는 재귀 알고리즘의 예입니다. 다음 사양 (4G 메모리, Intel Core i5 2.3GHz CPU, 64 비트 Windows 7)의 노트북에서이 함수는 10,000에 가까운 크기의 링크 된 목록에 대해 StackOverflow 오류가 발생합니다.
내 요점은 항상 시스템의 규모를 고려하여 재귀를 신중하게 사용해야한다는 것입니다. 종종 재귀는 더 잘 확장되는 반복 프로그램으로 변환 될 수 있습니다. (동일한 알고리즘의 하나의 반복 버전이 페이지 하단에 제공되며, 9 밀리 초에 1 백만 크기의 단일 연결 목록을 뒤집습니다.)
private static LinkedListNode doReverseRecursively(LinkedListNode x, LinkedListNode first){
LinkedListNode second = first.next;
first.next = x;
if(second != null){
return doReverseRecursively(first, second);
}else{
return first;
}
}
public static LinkedListNode reverseRecursively(LinkedListNode head){
return doReverseRecursively(null, head);
}
동일한 알고리즘의 반복 버전 :
public static LinkedListNode reverseIteratively(LinkedListNode head){
return doReverseIteratively(null, head);
}
private static LinkedListNode doReverseIteratively(LinkedListNode x, LinkedListNode first) {
while (first != null) {
LinkedListNode second = first.next;
first.next = x;
x = first;
if (second == null) {
break;
} else {
first = second;
}
}
return first;
}
public static LinkedListNode reverseIteratively(LinkedListNode head){
return doReverseIteratively(null, head);
}
공유 이 답변을 개선 따르다
생성 16 jan. 132013-01-16 19:49:49 s.
Yiling
2,3162골드 배지 2 개18은색 배지 18 개24브론즈 배지 24 개
JVM을 사용하면 랩톱의 사양이 실제로 중요하지 않습니다. - 케빈 10월 24일 '13 1시 48분에서
의견을 추가하다
삼
A StackOverflowError는 Java의 런타임 오류입니다.
JVM에서 할당 한 호출 스택 메모리 양을 초과하면 발생합니다.
StackOverflowErrorthrow되는 일반적인 경우는 과도한 딥 또는 무한 재귀로 인해 호출 스택이 초과되는 경우입니다 .
예:
public class Factorial {
public static int factorial(int n){
if(n == 1){
return 1;
}
else{
return n * factorial(n-1);
}
}
public static void main(String[] args){
System.out.println("Main method started");
int result = Factorial.factorial(-1);
System.out.println("Factorial ==>"+result);
System.out.println("Main method ended");
}
}
스택 추적 :
Main method started
Exception in thread "main" java.lang.StackOverflowError
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)
위의 경우 프로그래밍 방식으로 변경하면이를 방지 할 수 있습니다. 그러나 프로그램 논리가 정확하고 여전히 발생하면 스택 크기를 늘려야합니다.
공유 이 답변을 개선 따르다
생성 22 jul.
타 발렌도
6717은색 배지 7 개25브론즈 배지 25 개
생성 30 mar.
라훌 사
2694은색 배지 4 개13브론즈 배지 13 개
의견을 추가하다
삼
스택에는 OS에 따라 공간 제한이 있으며 일반 크기는 8MB입니다 (Ubuntu에서는 제한을 $ ulimit -u확인할 수 있으며 다른 OS에서도 유사하게 확인할 수 있습니다). 모든 프로그램은 런타임에 스택을 사용하지만 사용시기를 완전히 파악하려면 어셈블리 언어를 확인해야합니다. 예를 들어 x86_64에서 스택은 다음을 위해 사용됩니다.
절차 호출시 반송 주소 저장
지역 변수 저장
나중에 복원하기 위해 특수 레지스터 저장
프로 시저 호출에 인수 전달 (6 개 이상)
기타 : 사용되지 않은 임의의 스택 기반, 카나리아 값, 패딩 등
x86_64 (일반적인 경우)를 모르는 경우 사용중인 특정 high-lvl 프로그래밍 언어가 해당 작업으로 컴파일되는시기 만 알면됩니다. 예를 들어 C :
(1) → 함수 호출
(2) → 함수 호출의 지역 변수 (메인 포함)
(3) → 함수 호출의 지역 변수 (메인이 아님)
(4) → 함수 호출
(5) → 일반적으로 함수 호출, 일반적으로 스택 오버플로와 관련이 없습니다.
따라서 C에서는 지역 변수와 함수 호출 만 stack을 사용합니다 . 스택 오버플로를 만드는 두 가지 (고유 한?) 방법은 다음과 같습니다.
main 또는 호출 한 함수에서 너무 큰 지역 변수 선언 ( int array[10000][10000];)
매우 깊거나 무한한 재귀 (동시에 너무 많은 함수 호출).
피하려면 StackOverflowError다음을 수행하십시오.
로컬 변수가 너무 큰지 (1MB 정도) 확인 → 힙 (malloc / calloc 호출) 또는 전역 변수를 사용합니다.
무한 재귀 확인 →해야 할 일을 알고 있습니다.
정상적인 너무 깊은 재귀 확인 → 가장 쉬운 방법은 구현을 반복적으로 변경하는 것입니다.
전역 변수, 라이브러리 포함 등은 스택을 사용하지 않습니다.
위의 방법이 작동하지 않는 경우에만 특정 OS에서 스택 크기를 최대로 변경하십시오. 예를 들어 Ubuntu의 경우 : $ ulimit -s 32768(32MB). (이것은 내 스택 오버플로 오류에 대한 해결책이 아니지만 경험이 많지 않습니다)
C의 특수한 경우 및 / 또는 표준이 아닌 경우 (예 : 사용 alloc()및 유사)를 생략했습니다. 사용하는 경우 이미 수행중인 작업을 정확히 알고 있어야하기 때문입니다.
건배!
공유 이 답변을 개선 따르다
생성 9 jul.
생성 9 jul.
MrIo
841은색 배지 1 개6브론즈 배지 6 개
의견을 추가하다
1
위기 상황에서 아래 상황은 스택 오버플로 오류를 가져옵니다.
public class Example3 {
public static void main(String[] args) {
main(new String[1]);
}
}
공유 이 답변을 개선 따르다
생성 26 feb. 14:40:28
칼리아 판
5606은색 배지 6 개24브론즈 배지 24 개
의견을 추가하다
0
이것은 전형적인 경우입니다 java.lang.StackOverflowError... 방법은 재귀 적 없음 출구 자신을 호출 doubleValue(), floatValue()등
Rational.java
public class Rational extends Number implements Comparable
private int num;
private int denom;
public Rational(int num, int denom) {
this.num = num;
this.denom = denom;
}
public int compareTo(Rational r) {
if ((num / denom) - (r.num / r.denom) > 0) {
return +1;
} else if ((num / denom) - (r.num / r.denom) < 0) {
return -1;
}
return 0;
}
public Rational add(Rational r) {
return new Rational(num + r.num, denom + r.denom);
}
public Rational sub(Rational r) {
return new Rational(num - r.num, denom - r.denom);
}
public Rational mul(Rational r) {
return new Rational(num * r.num, denom * r.denom);
}
public Rational div(Rational r) {
return new Rational(num * r.denom, denom * r.num);
}
public int gcd(Rational r) {
int i = 1;
while (i != 0) {
i = denom % r.denom;
denom = r.denom;
r.denom = i;
}
return denom;
}
public String toString() {
String a = num + "/" + denom;
return a;
}
public double doubleValue() {
return (double) doubleValue();
}
public float floatValue() {
return (float) floatValue();
}
public int intValue() {
return (int) intValue();
}
public long longValue() {
return (long) longValue();
}
}
Main.java
public class Main {
public static void main(String[] args) {
Rational a = new Rational(2, 4);
Rational b = new Rational(2, 6);
System.out.println(a + " + " + b + " = " + a.add(b));
System.out.println(a + " - " + b + " = " + a.sub(b));
System.out.println(a + " * " + b + " = " + a.mul(b));
System.out.println(a + " / " + b + " = " + a.div(b));
Rational[] arr = {new Rational(7, 1), new Rational(6, 1),
new Rational(5, 1), new Rational(4, 1),
new Rational(3, 1), new Rational(2, 1),
new Rational(1, 1), new Rational(1, 2),
new Rational(1, 3), new Rational(1, 4),
new Rational(1, 5), new Rational(1, 6),
new Rational(1, 7), new Rational(1, 8),
new Rational(1, 9), new Rational(0, 1)};
selectSort(arr);
for (int i = 0; i < arr.length - 1; ++i) {
if (arr[i].compareTo(arr[i + 1]) > 0) {
System.exit(1);
}
}
Number n = new Rational(3, 2);
System.out.println(n.doubleValue());
System.out.println(n.floatValue());
System.out.println(n.intValue());
System.out.println(n.longValue());
}
public static <T extends Comparable<? super T>> void selectSort(T[] array) {
T temp;
int mini;
for (int i = 0; i < array.length - 1; ++i) {
mini = i;
for (int j = i + 1; j < array.length; ++j) {
if (array[j].compareTo(array[mini]) < 0) {
mini = j;
}
}
if (i != mini) {
temp = array[i];
array[i] = array[mini];
array[mini] = temp;
}
}
}
}
결과
2/4 + 2/6 = 4/10
Exception in thread "main" java.lang.StackOverflowError
2/4 - 2/6 = 0/-2
at com.xetrasu.Rational.doubleValue(Rational.java:64)
2/4 * 2/6 = 4/24
at com.xetrasu.Rational.doubleValue(Rational.java:64)
2/4 / 2/6 = 12/8
at com.xetrasu.Rational.doubleValue(Rational.java:64)
at com.xetrasu.Rational.doubleValue(Rational.java:64)
at com.xetrasu.Rational.doubleValue(Rational.java:64)
at com.xetrasu.Rational.doubleValue(Rational.java:64)
at com.xetrasu.Rational.doubleValue(Rational.java:64)
다음은 StackOverflowErrorOpenJDK 7 의 소스 코드입니다 .
공유 이 답변을 개선 따르다
생성 02 apr. 182018-04-02 12:41:28 ss
생성 02 apr. 182018-04-02 12:36:28 s.
user8389458
의견을 추가하다
-1
여기에 예가 있습니다.
public static void main(String[] args) {
System.out.println(add5(1));
}
public static int add5(int a) {
return add5(a) + 5;
}
StackOverflowError는 기본적으로 자신을 호출하고 무한대 (또는 StackOverflowError가 발생할 때까지)를 수행하려고 할 때 발생합니다.
add5(a) 자신을 호출 한 다음 다시 호출합니다.
공유 이 답변을 개선 따르다
생성 11 feb. 162016-02-11 23:02:22 s.
존 S.
5761골드 배지 1 개삼은색 배지 3 개13브론즈 배지 13 개
의견을 추가하다
-1
"스택 오버런 (오버플로)"이라는 용어가 자주 사용되지만 잘못된 이름입니다. 공격은 스택을 오버플로하지 않고 스택에 버퍼링합니다.
-Dr. Dieter Gollmann 의 강의 슬라이드에서
'컴퓨터' 카테고리의 다른 글
데이터베이스와 함께 애플리케이션 제공 (0) | 2020.11.22 |
---|---|
배치 파일에 특수 문자가 포함 된 ASCII 아트를 어떻게 에코합니까? (0) | 2020.11.22 |
JSONObject의 순서를 유지하는 방법 (0) | 2020.11.22 |
가상 개인 서버 (0) | 2020.07.05 |
공유기 포트 포워딩 방법 (1) | 2020.07.05 |