2010-04-12 1 views

답변

9

Java가 새 스레드를 만들면 해당 스레드의 스택에 고정 된 크기의 메모리 블록이 미리 할당됩니다. 해당 메모리 블록의 크기를 줄이면 메모리가 부족 해지는 것을 피할 수 있습니다. 특히 많은 스레드가있는 경우 - 메모리 절약은 스택 크기와 스레드 수를 곱한 값입니다.

이렇게하는 단점은 스택 오버플로 오류가 발생할 가능성이 높아진다는 것입니다.

스레드 스택은 JVM 힙 외부에서 생성되므로 힙에 사용할 수있는 메모리가 충분하더라도 메모리가 부족하거나 주소가 부족하여 스레드 스택을 만들지 못하는 경우가 있습니다 공간, Tom Hawtin이 정확하게 지적했듯이).

+0

ok, VirtualVm을 사용하여 추적하고 스택 공간을 변경해야하는지 여부를 알아 봅니다. 내 생각 엔 그럴 것 같지 않아. – djangofan

2

프로세스에는 N 개의 스레드가 있고 각 스레드 스택에는 M 바이트의 메모리가 할당됩니다. 스택 사용을 위해 할당 된 총 메모리는 N x M입니다.

스택 수 (N)를 줄이거 나 각 스레드 (M)에 할당 된 메모리를 줄임으로써 스택이 소비하는 총 메모리를 줄일 수 있습니다.


종종 스레드가 모든 스택을 사용하지는 않습니다. "경우에 따라"나중에 할당 될 것이지만 스레드가 깊은 호출 경로를 사용하지 않거나 재귀를 사용하지 않으면 할당 된 스택 공간을 모두 필요로하지 않을 수도 있습니다.

최적의 스택 크기를 찾는 것이 예술 일 수 있습니다.

4

주소 공간이 고갈 될 수 있다는 32 비트 JVM에 문제가 있습니다. 최대 스택 크기를 줄이면 일반적으로 실제로 할당 된 메모리 양이 줄어들지 않습니다. 2k의 1k의 스택을 위해 예약 된 256kB를 가진 8k 쓰레드를 고려해보십시오. 거기에는 31 비트의 주소 공간 (2GB)이 있습니다.

문제는 64 비트 JVM에서 모두 사라지지만 (참조가 두 배나 크기 때문에 실제 메모리 양은 약간 늘어납니다). 또는 비 블로킹 API를 사용하면 많은 스레드가 필요하지 않게 될 수 있습니다.

+1

핫스팟 6u14에 압축 개체 포인터가 도입되어이를 완화합니다. http : //wikis.sun.co.kr/display/HotSpotInternals/CompressedOops –

2

스레드 스택 크기를 변경하기 전에 다른 것들 (예 : 생존자 비율 또는 클래스 정의에 할당 된 공간의 크기 변경)을 시도합니다. 바로, 따라서 매우 쉽게 스택 오버플로 오류 얻을 구하기 힘든 것입니다 (메모리 부족 오류로 똑같이 치명적이다.)


심지어 면밀하게 조사한 후이 권리를받은 적이 없다. 그러나 다시 한번, 스레드 스택 크기를 변경하여 미세 조정할 수있는 웹 응용 프로그램/컨테이너 조합을 접한 적이 없었을 것입니다. 생존자 비율을 수정 한 결과가 훨씬 좋았습니다 (치명적이지는 않습니다). 하지만 그건 나의 직장 경험되었습니다. 다른 작업 공간 및 응용 프로그램에서 YMMV.

관련 문제