2012-02-15 7 views
2

대용량의 데이터를 처리해야하는이 Java 시뮬레이터가 있습니다. 그것은 잘 작동하지만 하나는 다른 큰 배열과 함께 int[100000][100][2]의 배열까지 일어난다. 프로그램은 그 메모리가 부족하다고 말합니다. (Java.lang.outOfMemoryError)힙 공간을 채우기 전에 Java 충돌이 발생했습니다.

괜찮아요. 더 많은 메모리를 제공하지만, 2GB를 허용하더라도 항상 ~ 300M 정도가 부족한 것처럼 보입니다. 이것은 모두 작업 관리자를 보는 것입니다.

내 시스템에 문제가 있습니까? 아니면 처리해야 할 Java 항목입니까?

@DanielPryden

OS : 윈 보드의 램

JVM 명령 7 32 비트 4기가바이트 : 자바 -Xmx2048m -Xms2048M 시뮬레이터

오류 데이터 :가 IDE에서 얻을 수 있었다 (IntelliJ를 사용) . 나는 cmd에서 그것을 어떻게하는지 모른다. 나는 이것이 당신이 찾고있는 것이라고 생각합니다.

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 
    at Simulator.main(Simulator.java:63) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 
+0

큰 힙 크기를 지정하려면 java를 실행할 때 -Xmx2GB 플래그를 사용하고 있습니까? –

+0

'어떻게 할 수 있습니까? -Xmx로? 그게 효과가있다. –

+0

cmd에서 실행중인 -Xmx2048M -Xms2048M을 사용합니다. –

답변

4

32 비트 Windows OS에서 실행중인 경우 전체 2GB를 할당 할 수 없습니다. Windows 내부 구조에 대해 불만을 나타낼지라도 사용할 수있는 가장 큰 주소 공간은 3GB이며 연속적으로 연결되는 것은 아닙니다 (JVM은 Java 힙을 빌드하는 데 연속적인 공간이 필요합니다). 실제로 Sun/Oracle JVM을 사용하면 약 1.5GB 이상의 힙을 성공적으로 할당 할 수 없었습니다. JNI를 사용하는 경우 연결 가능한 모든 DLL에서 가능한 최대 힙이 줄어 듭니다. in.

큰 힙이 정말로 필요한 경우 가능한 모든 경우 64 비트 OS로 이동하는 것이 좋습니다. 두 번째로, 여기에있는 다른 답변에서 지적했듯이 연속되지 않는 메모리를 할당 할 수 있다면 성공할 가능성이 더 높습니다. LinkedList 또는 다른 청크로 데이터를 할당하는 다른 구조를 사용하십시오. 여기에 약간의 절충안이 있습니다. 아마도 각 청크에 적어도 64Kb의 배열이 포함되기를 원할 것입니다.

마지막으로, 처리를 별도의 프로세스로 나누는 방법, 즉 작동 할 자체 데이터 세트가있는 여러 개의 Java 인스턴스를 실행하고 소켓 또는 그들 사이에서 통신 할 파일. 즉, 32 비트 Windows OS를 사용하면 더 많은 양의 RAM을 제외하고 4GB RAM을 사용할 수 없을 것입니다.

+0

모든 답변은 훌륭한 제안처럼 들리지만,이 의견은 더 간결하다고 생각했습니다. 브라보,하지만 모두. –

5

힙 조각화 문제가있을 수 있습니다. -Xmx2GB를 설정하더라도 위의 정수 배열은 블록 연속 메모리가 필요합니다. 또한 최소 힙 크기를 고정하는 것이 좋습니다 (예 : -Xms2GB). 물론 OS 오버 헤드, 다른 프로세스 등으로 인해 실제로 2GB를 초과해야합니다.

또는 이러한 연속 블록이 실제로 필요한지 확인하기 위해 데이터 구조를 다시 방문 할 수도 있습니다. 어떤 식 으로든 그것을 깨뜨리는 것은 커다란 연속적인 메모리 블록에 대한 요구를 줄여 줄 수 있습니다.

2

힙 메모리가 세 공간 사이 구분됩니다 기본적으로

  • 구세대
  • 생존자 공간
  • 에덴 공간

를 가상 컴퓨터가 커지거나 각 컬렉션에서 힙을 축소 특정 범위 내의 각 콜렉션에서 오브젝트를 살릴 수있는 여유 공간의 비율을 유지하려고 시도합니다. 이 대상 범위는 -XX : MinHeapFreeRatio = 및 -XX : MaxHeapFreeRatio = 매개 변수에 의해 백분율로 설정되며 총 크기는 아래 -Xms 이상 -Xmx로 제한됩니다.

내 jvm (1.6.26)의 기본 비율은 30/70이므로 구형 세대의 최대 개체 크기는 -Xmx1G에서 700Mb로 제한됩니다.

그러나 jvm 옵션을 사용하여 생성 크기를 조정할 수 있습니다. 예를 들어 매개 변수 -Xmx1G -XX : NewRatio = 10을 사용하여 클래스를 실행할 수 있으며 더 큰 객체를 메모리에 배치 할 수 있습니다.

Java가 메모리와 같이 큰 모노리딕 객체를 배열하도록 설계되지 않은 것처럼 보입니다. 응용 프로그램에서 메모리의 일반적인 사용은 상대적으로 작은 개체의 무리의 그래프이며, 일반적으로 모든 공간에서 공간이 부족한 경우에만 OutOfMemoryError를 얻습니다.

Ergonomics in the 5.0 Java[tm] Virtual Machine

Tuning Garbage Collection with the 5.0 Java[tm] Virtual Machine

편집 :

아래는 몇 가지 (읽기 흥미) 유용한 기사입니다 내 상자에이를 재현 할 수없는 (맥 OS X, 8GB의 RAM). 단일 어레이가 약 200Mb + 메모리를 차지한다는 점을 감안할 때,이 크기 (메모리 크기가 아님)를 유발하는이 크기의 연속적인 메모리 블록이 없다는 것에 동의합니다. 픽스 - 컬렉션을 일반 배열과 함께 사용하거나 더 많은 메모리를 구입하는 경우 (권장 :-))

+0

예제를 제공해 주시겠습니까? 나는 당신이 묘사 한 것을 사용하는 다른 방법을 시도했지만 도움이되지는 않습니다. –

관련 문제