programing tip

64 비트 OS에서 32 비트 JVM의 최대 Java 힙 크기

itbloger 2020. 8. 13. 07:59
반응형

64 비트 OS에서 32 비트 JVM의 최대 Java 힙 크기


32 비트 OS의 최대 주소 지정 가능 메모리 크기가 4GB이고 JVM의 최대 힙 크기는 예약 할 수있는 연속 여유 메모리 양에 따라 달라진다는 점을 고려할 때 32 비트 OS의 최대 힙 크기에 대한 질문이 아닙니다.

64 비트 OS에서 실행되는 32 비트 JVM의 최대 (이론적 및 실질적으로 달성 가능한) 힙 크기를 아는 데 더 관심이 있습니다. 기본적으로 SO 관련 질문의 그림 과 유사한 답변을 찾고 있습니다.

64 비트 대신 32 비트 JVM이 사용되는 이유는 기술적 인 것이 아니라 관리 / 관료적입니다. 프로덕션 환경에 64 비트 JVM을 설치하기에는 너무 늦었을 것입니다.


하나의 큰 메모리 청크를 갖고 원시 포인터를 사용할 것으로 예상되는 32 비트 JVM은 4Gb 이상을 사용할 수 없습니다 (포인터에도 적용되는 32 비트 제한이기 때문에). 여기에는 Sun과 IBM 구현도 포함됩니다. 예를 들어 JRockit 또는 다른 사람들이 32 비트 구현과 함께 대용량 메모리 옵션을 가지고 있는지 모르겠습니다.

이 한계에 도달 할 것으로 예상되는 경우 프로덕션 환경에 대해 64 비트 JVM의 유효성을 검사하는 병렬 트랙을 시작하는 것을 강력히 고려하여 32 비트 환경이 중단 될 때 준비 할 수 있도록해야합니다. 그렇지 않으면 압력을 받아 그 일을해야하는데 결코 좋지 않습니다.


2014-05-15 수정 : Oracle FAQ :

32 비트 JVM의 이론상 최대 힙 한계는 4G입니다. 사용 가능한 스왑, 커널 주소 공간 사용, 메모리 조각화 및 VM 오버 헤드와 같은 다양한 추가 제약으로 인해 실제로 제한은 훨씬 낮을 수 있습니다. 대부분의 최신 32 비트 Windows 시스템에서 최대 힙 크기는 1.4G에서 1.6G입니다. 32 비트 Solaris 커널에서 주소 공간은 2G로 제한됩니다. 32 비트 VM을 실행하는 64 비트 운영 체제에서는 최대 힙 크기가 더 높아져 많은 Solaris 시스템에서 4G에 접근 할 수 있습니다.

( http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit )


Java Runtime에 요청할 수 있습니다.

public class MaxMemory {
    public static void main(String[] args) {
        Runtime rt = Runtime.getRuntime();
        long totalMem = rt.totalMemory();
        long maxMem = rt.maxMemory();
        long freeMem = rt.freeMemory();
        double megs = 1048576.0;

        System.out.println ("Total Memory: " + totalMem + " (" + (totalMem/megs) + " MiB)");
        System.out.println ("Max Memory:   " + maxMem + " (" + (maxMem/megs) + " MiB)");
        System.out.println ("Free Memory:  " + freeMem + " (" + (freeMem/megs) + " MiB)");
    }
}

기본 힙 할당을 기반으로 "최대 메모리"를보고합니다. 따라서 여전히 -Xmx( 핫스팟에서 ) 게임을해야합니다 . Windows 7 Enterprise 64 비트에서 실행되는 32 비트 HotSpot JVM은 최대 1577MiB를 할당 할 수 있습니다.

[C : scratch]> java -Xmx1600M MaxMemory
VM 초기화 중 오류 발생
개체 힙을위한 충분한 공간을 예약 할 수 없습니다.
자바 가상 머신을 만들 수 없습니다.
[C : 스크래치]> java -Xmx1590M MaxMemory
총 메모리 : 2031616 (1.9375MiB)
최대 메모리 : 1654456320 (1577.8125 MiB)
여유 메모리 : 1840872 (1.75559234619 MiB)
[C : 스크래치]>

반면에 64 비트 동일한 OS에 JVM 물론 그것의 매우 높은 (약 3TiB)

[C : 스크래치]> java -Xmx3560G MaxMemory
VM 초기화 중 오류 발생
개체 힙을위한 충분한 공간을 예약 할 수 없습니다.
[C : scratch]> java -Xmx3550G MaxMemory
총 메모리 : 94240768 (89.875MiB)
최대 메모리 : 3388252028928 (3184151.84297 MiB)
여유 메모리 : 93747752 (89.4048233032 MiB)
[C : 스크래치]>

다른 사람들이 이미 언급했듯이 OS에 따라 다릅니다.

  • 32 비트 Windows의 경우 : 2GB 미만입니다 ( Windows 내부 책 에 사용자 프로세스 용으로 2GB가 표시됨)
  • 32 비트 BSD / Linux : <3GB (Devil Book에서 제공)
  • 32 비트 MacOS X : <4GB ( Mac OS X 내부 책자)
  • 32 비트 Solaris에 대해 잘 모르겠습니다. 위 코드를 사용해보고 알려주십시오.

64 비트 호스트 OS의 경우 JVM이 32 비트이면 위에서 설명한 것처럼 여전히 종속됩니다.

-업데이트 20110905 : 다른 관찰 / 세부 사항을 지적하고 싶었습니다.

  • 이것을 실행 한 하드웨어는 6GB의 실제 RAM이 설치된 64 비트였습니다. 운영 체제는 Windows 7 Enterprise, 64 비트였습니다.
  • Runtime.MaxMemory할당 할 수있는 실제 양은 운영 체제의 작업 세트 에 따라 다릅니다 . VirtualBox도 실행하는 동안 이것을 실행 한 적이 있는데 HotSpot JVM을 성공적으로 시작할 없고-Xmx1590M 더 작아야한다는 것을 알았습니다. 이것은 또한 당시 작업 세트 크기에 따라 1590M 이상을 얻을 수 있음을 의미합니다 (Windows의 설계로 인해 32 비트의 경우 여전히 2GiB 미만이라고 유지하지만).

어떤 OS를 지정하지 않습니다 .

Windows (내 애플리케이션의 경우-장기 실행 위험 관리 애플리케이션)에서는 Windows 32 비트에서 1280MB 이상을 사용할 수 없음을 확인했습니다. 64 비트에서 32 비트 JVM을 실행하는 것이 어떤 차이를 만들지 모르겠습니다.

우리는 앱을 Linux로 이식했고 64 비트 하드웨어에서 32 비트 JVM을 실행하고 있으며 2.2GB VM을 매우 쉽게 실행했습니다.

가장 큰 문제는 메모리를 사용하는 용도에 따라 GC입니다.


에서 4.1.2 힙 크기 조정 :

"32 비트 프로세스 모델의 경우 프로세스의 최대 가상 주소 크기는 일반적으로 4GB이지만 일부 운영 체제에서는이를 2GB 또는 3GB로 제한합니다. 최대 힙 크기는 일반적으로 2GB 제한에 대해 -Xmx3800m (1600m)입니다. ), 실제 제한은 응용 프로그램에 따라 다릅니다. 64 비트 프로세스 모델의 경우 최대 값은 본질적으로 무제한입니다. "

여기에서 꽤 좋은 대답을 찾았습니다 . Windows XP의 Java 최대 메모리 .


최근에 이것에 대한 경험이 있습니다. 최근에 Solaris (x86-64 버전 5.10)에서 Linux (RedHat x86-64)로 이식했으며 Linux에서 Solaris보다 32 비트 JVM 프로세스에 사용할 수있는 메모리가 적다는 것을 깨달았습니다.

Solaris의 경우 거의 4GB (http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit)가됩니다.

지난 몇 년 동안 Solaris에서 문제없이 -Xms2560m -Xmx2560m -XX : MaxPermSize = 512m -XX : PermSize = 512m 으로 앱을 실행 했습니다. 그것을 리눅스로 옮기려고 시도했고 시작할 때 무작위로 메모리 부족 오류가 발생했습니다. -Xms2300 -Xmx2300 에서만 일관되게 시작되도록 할 수 있었습니다 . 그런 다음 지원을 통해 이에 대해 조언을 받았습니다.

Linux의 32 비트 프로세스는 주소 지정 가능한 최대 주소 공간이 3GB (3072mb) 인 반면 Solaris에서는 전체 4GB (4096mb)입니다.


64 비트 OS에서 32 비트 JVM의 제한은 32 비트 OS에서 32 비트 JVM의 제한과 정확히 동일합니다. 결국 32 비트 JVM은 32 비트 가상 머신 (가상화 측면에서)에서 실행되므로 64 비트 OS / 머신에서 실행되고 있는지 알 수 없습니다.

32 비트 OS에 비해 64 비트 OS에서 32 비트 JVM을 실행할 때의 한 가지 장점은 더 많은 물리적 메모리를 가질 수 있으므로 스왑 / 페이징 빈도가 줄어든다는 것입니다. 그러나 이러한 이점은 여러 프로세스가있을 때만 완전히 실현됩니다.


64 비트 대신 32 비트 JVM이 사용되는 이유는 기술적 인 것이 아니라 관리 / 관료적입니다.

BEA에서 일할 때 평균 애플리케이션이 실제로 64 비트 JVM에서 더 느리게 실행되고 32 비트 JVM에서 실행될 때 더 느리게 실행 된다는 사실을 발견했습니다 . 어떤 경우에는 성능 저하가 25 %까지 느려졌습니다. 따라서 응용 프로그램에 추가 메모리가 모두 필요하지 않는 한 32 비트 서버를 더 많이 설정하는 것이 좋습니다.

내가 회상했듯이, BEA 전문 서비스 직원이 만난 64 비트 사용에 대한 가장 일반적인 세 ​​가지 기술적 이유는 다음과 같습니다.

  1. 애플리케이션은 여러 개의 거대한 이미지를 조작하고 있었지만
  2. 응용 프로그램은 엄청난 수의 처리를하고 있었는데
  3. 응용 프로그램에 메모리 누수가 있었고 고객은 정부 계약에서 최고였으며 메모리 누수를 추적하는 데 시간과 비용을 들이고 싶지 않았습니다. (대량 메모리 힙을 사용하면 MTBF가 증가하고 프라임은 여전히 ​​지불됩니다)

.


현재 Oracle이 소유하고있는 JROCKIT JVM은 비 연속적인 힙 사용을 지원하므로 JVM이 64 비트 Windows OS에서 실행될 때 32 비트 JVM이 3.8GB 이상의 메모리에 액세스 할 수 있습니다. (32 비트 OS에서 실행하는 경우 2.8GB).

http://blogs.oracle.com/jrockit/entry/how_to_get_almost_3_gb_heap_on_windows

JVM은 다음 사이트에서 무료로 다운로드 할 수 있습니다 (등록 필요).

http://www.oracle.com/technetwork/middleware/jrockit/downloads/index.html


다음은 Solaris 및 Linux 64 비트에서 몇 가지 테스트입니다.

Solaris 10-SPARC-32GB RAM (약 9GB 여유 공간)이있는 T5220 시스템

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3750m MaxMemory
Error occurred during initialization of VM
Could not reserve space for ObjectStartArray
$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3700m MaxMemory
Total Memory: 518520832 (494.5 MiB)
Max Memory:   3451912192 (3292.0 MiB)
Free Memory:  515815488 (491.91998291015625 MiB)
Current PID is: 28274
Waiting for user to press Enter to finish ...

$ java -version
java version "1.6.0_30"
Java(TM) SE Runtime Environment (build 1.6.0_30-b12)
Java HotSpot(TM) Server VM (build 20.5-b03, mixed mode)

$ which java
/usr/bin/java
$ file /usr/bin/java
/usr/bin/java: ELF 32-bit MSB executable SPARC Version 1, dynamically linked, not stripped, no debugging information available

$ prstat -p 28274
   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
28274 user1     670M   32M sleep   59    0   0:00:00 0.0% java/35

BTW : 분명히 Java는 시작시 실제 메모리를 많이 할당하지 않습니다. 시작된 인스턴스 당 약 100MB 만 소요되는 것 같습니다 (10 개 시작)

Solaris 10-x86-8GB RAM이있는 VMWare VM (약 3GB 여유 공간 *)

3GB 여유 RAM은 사실이 아닙니다. ZFS 캐시가 사용하는 많은 RAM이 있지만 정확히 얼마나 많은지 확인할 수있는 루트 액세스 권한이 없습니다.

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3650m MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3600m MaxMemory
Total Memory: 516423680 (492.5 MiB)
Max Memory:   3355443200 (3200.0 MiB)
Free Memory:  513718336 (489.91998291015625 MiB)
Current PID is: 26841
Waiting for user to press Enter to finish ...

$ java -version
java version "1.6.0_41"
Java(TM) SE Runtime Environment (build 1.6.0_41-b02)
Java HotSpot(TM) Server VM (build 20.14-b01, mixed mode)

$ which java
/usr/bin/java

$ file /usr/bin/java
/usr/bin/java:  ELF 32-bit LSB executable 80386 Version 1 [FPU], dynamically linked, not stripped, no debugging information available

$ prstat -p 26841
   PID USERNAME  SIZE   RSS STATE  PRI NICE      TIME  CPU PROCESS/NLWP
26841 user1     665M   22M sleep   59    0   0:00:00 0.0% java/12

RedHat 5.5-x86-4GB RAM이있는 VMWare VM (약 3.8GB 사용-버퍼에 200MB, 캐시에 3.1GB이므로 약 3GB 여유 공간)

$ alias java='$HOME/jre/jre1.6.0_34/bin/java'

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3500m MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3450m MaxMemory
Total Memory: 514523136 (490.6875 MiB)
Max Memory:   3215654912 (3066.6875 MiB)
Free Memory:  511838768 (488.1274871826172 MiB)
Current PID is: 21879
Waiting for user to press Enter to finish ...

$ java -version
java version "1.6.0_34"
Java(TM) SE Runtime Environment (build 1.6.0_34-b04)
Java HotSpot(TM) Server VM (build 20.9-b04, mixed mode)

$ file $HOME/jre/jre1.6.0_34/bin/java
/home/user1/jre/jre1.6.0_34/bin/java: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped

$ cat /proc/21879/status | grep ^Vm
VmPeak:  3882796 kB
VmSize:  3882796 kB
VmLck:         0 kB
VmHWM:     12520 kB
VmRSS:     12520 kB
VmData:  3867424 kB
VmStk:        88 kB
VmExe:        40 kB
VmLib:     14804 kB
VmPTE:        96 kB

JRE 7을 사용하는 동일한 시스템

$ alias java='$HOME/jre/jre1.7.0_21/bin/java'

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3500m MaxMemory
Error occurred during initialization of VM
Could not reserve enough space for object heap
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

$ java -XX:PermSize=128M -XX:MaxPermSize=256M -Xms512m -Xmx3450m MaxMemory
Total Memory: 514523136 (490.6875 MiB)
Max Memory:   3215654912 (3066.6875 MiB)
Free Memory:  511838672 (488.1273956298828 MiB)
Current PID is: 23026
Waiting for user to press Enter to finish ...

$ java -version
java version "1.7.0_21"
Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) Server VM (build 23.21-b01, mixed mode)

$ file $HOME/jre/jre1.7.0_21/bin/java
/home/user1/jre/jre1.7.0_21/bin/java: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped

$ cat /proc/23026/status | grep ^Vm
VmPeak:  4040288 kB
VmSize:  4040288 kB
VmLck:         0 kB
VmHWM:     13468 kB
VmRSS:     13468 kB
VmData:  4024800 kB
VmStk:        88 kB
VmExe:         4 kB
VmLib:     10044 kB
VmPTE:       112 kB

훨씬 나아질 것

For a 32-bit JVM running on a 64-bit host, I imagine what's left over for the heap will be whatever unfragmented virtual space is available after the JVM, it's own DLL's, and any OS 32-bit compatibility stuff has been loaded. As a wild guess I would think 3GB should be possible, but how much better that is depends on how well you are doing in 32-bit-host-land.

Also, even if you could make a giant 3GB heap, you might not want to, as this will cause GC pauses to become potentially troublesome. Some people just run more JVM's to use the extra memory rather than one giant one. I imagine they are tuning the JVM's right now to work better with giant heaps.

It's a little hard to know exactly how much better you can do. I guess your 32-bit situation can be easily determined by experiment. It's certainly hard to predict abstractly, as a lot of things factor into it, particularly because the virtual space available on 32-bit hosts is rather constrained.. The heap does need to exist in contiguous virtual memory, so fragmentation of the address space for dll's and internal use of the address space by the OS kernel will determine the range of possible allocations.

The OS will be using some of the address space for mapping HW devices and it's own dynamic allocations. While this memory is not mapped into the java process address space, the OS kernel can't access it and your address space at the same time, so it will limit the size of any program's virtual space.

Loading DLL's depends on the implementation and the release of the JVM. Loading the OS kernel depends on a huge number of things, the release, the HW, how many things it has mapped so far since the last reboot, who knows...

In summary

I bet you get 1-2 GB in 32-bit-land, and about 3 in 64-bit, so an overall improvement of about 2x.


On Solaris the limit has been about 3.5 GB since Solaris 2.5. (about 10 years ago)


I was having the same problems with the JVM that App Inventor for Android Blocks Editor uses. It sets the heap at 925m max. This is not enough but I couldn't set it more than about 1200m, depending on various random factors on my machine.

I downloaded Nightly, the beta 64-bit browser from Firefox, and also JAVA 7 64 bit version.

I haven't yet found my new heap limit, but I just opened a JVM with a heap size of 5900m. No problem!

I am running Win 7 64 bit Ultimate on a machine with 24gb RAM.


I have tried setting the heap size upto 2200M on 32bit Linux machine and JVM worked fine. The JVM didnt start when I set it to 2300M.


This is heavy tunning, but you can get a 3gb heap.

http://www.microsofttranslator.com/bv.aspx?from=&to=en&a=http://forall.ru-board.com/egor23/online/FAQ/Virtual_Memory/Limits_Virtual_Memory.html


one more point here for hotspot 32-bit JVM:- the native heap capacity = 4 Gig – Java Heap - PermGen;

It can get especially tricky for 32-bit JVM since the Java Heap and native Heap are in a race. The bigger your Java Heap, the smaller the native Heap. Attempting to setup a large Heap for a 32-bit VM e.g .2.5 GB+ increases risk of native OutOfMemoryError depending of your application(s) footprint, number of Threads etc.


Theoretical 4gb, but in practice (for IBM JVM):

Win 2k8 64, IBM Websphere Application Server 8.5.5 32bit

C:\IBM\WebSphere\AppServer\bin>managesdk.bat -listAvailable -verbose CWSDK1003I: Доступные SDK: CWSDK1005I: Имя SDK: 1.6_32 - com.ibm.websphere.sdk.version.1.6_32=1.6 - com.ibm.websphere.sdk.bits.1.6_32=32 - com.ibm.websphere.sdk.location.1.6_32=${WAS_INSTALL_ROOT}/java - com.ibm.websphere.sdk.platform.1.6_32=windows - com.ibm.websphere.sdk.architecture.1.6_32=x86_32 - com.ibm.websphere.sdk.nativeLibPath.1.6_32=${WAS_INSTALL_ROOT}/lib/native/win /x86_32/ CWSDK1001I: Задача managesdk выполнена успешно. C:\IBM\WebSphere\AppServer\java\bin>java -Xmx2036 MaxMemory JVMJ9GC017E -Xmx слишком мала, должна быть не меньше 1 M байт JVMJ9VM015W Ошибка инициализации для библиотеки j9gc26(2): Не удалось инициализи ровать Could not create the Java virtual machine. C:\IBM\WebSphere\AppServer\java\bin>java -Xmx2047M MaxMemory Total Memory: 4194304 (4.0 MiB) Max Memory: 2146435072 (2047.0 MiB) Free Memory: 3064536 (2.9225692749023438 MiB) C:\IBM\WebSphere\AppServer\java\bin>java -Xmx2048M MaxMemory JVMJ9VM015W Ошибка инициализации для библиотеки j9gc26(2): Не удалось создать эк земпляр кучи; запрошено 2G Could not create the Java virtual machine.

RHEL 6.4 64, IBM Websphere Application Server 8.5.5 32bit

[bin]./java -Xmx3791M MaxMemory Total Memory: 4194304 (4.0 MiB) Max Memory: 3975151616 (3791.0 MiB) Free Memory: 3232992 (3.083221435546875 MiB) [root@nagios1p bin]# ./java -Xmx3793M MaxMemory Total Memory: 4194304 (4.0 MiB) Max Memory: 3977248768 (3793.0 MiB) Free Memory: 3232992 (3.083221435546875 MiB) [bin]# /opt/IBM/WebSphere/AppServer/bin/managesdk.sh -listAvailable -verbose CWSDK1003I: Available SDKs : CWSDK1005I: SDK name: 1.6_32 - com.ibm.websphere.sdk.version.1.6_32=1.6 - com.ibm.websphere.sdk.bits.1.6_32=32 - com.ibm.websphere.sdk.location.1.6_32=${WAS_INSTALL_ROOT}/java - com.ibm.websphere.sdk.platform.1.6_32=linux - com.ibm.websphere.sdk.architecture.1.6_32=x86_32 -com.ibm.websphere.sdk.nativeLibPath.1.6_32=${WAS_INSTALL_ROOT}/lib/native/linux/x86_32/ CWSDK1001I: Successfully performed the requested managesdk task.

참고URL : https://stackoverflow.com/questions/1434779/maximum-java-heap-size-of-a-32-bit-jvm-on-a-64-bit-os

반응형