요즘 자바 애플릿은 대중적인 웹 기술은 아니지만, 리눅스 서버에 자바 가상 머신(JVM)을 직접 배포해야 할 이유는 여전히 많습니다. 그런데 물리 서버든 독립된 가상 머신(VM)이든 리눅스에서 java 명령어를 실행하려고 하면 "VM 초기화 중 오류가 발생했습니다. 개체 힙(object heap)을 위한 충분한 공간을 예약할 수 없습니다"라는 메시지를 만나게 되는 경우가 있습니다.
실제로는 명령어를 실행할 만큼 충분한 RAM이 있는 경우가 대부분이라 다소 의아하게 느껴질 수 있지만, 이는 주로 물리적·가상적 메모리 페이지가 사용되는 방식의 특수한 특성 때문입니다. 적절히 큰 크기를 지정해 주면 이 메시지를 완전히 우회하여 java 명령어를 평소처럼 실행할 수 있습니다.
방법 1: 명령줄 옵션으로 힙 크기 지정
java를 실행하다 이 메시지를 받았다면, 이미 free 명령어를 통해 프로그램을 구동할 메모리가 충분한지 확인해 보았을 것입니다.
테스트 장비에는 약 2.3GB의 물리적 RAM이 있었고, 가상 메모리 페이지는 하나도 사용되지 않은 상태였습니다. 만약 메모리가 부족하다는 사실을 발견했다면, 다시 시도하기 전에 실행 중인 다른 프로세스를 종료하는 것이 좋습니다. 반대로 여유 메모리가 넉넉하다면 힙 크기를 직접 지정하는 방법을 시도해 볼 수 있습니다.
예를 들어 테스트 환경에서는 java -Xms256m -Xmx512M 형태로 명령어를 실행했고, 기대한 대로 정상적으로 작동했습니다. 이 두 옵션은 JVM이 시작 시점에 예약하려는 힙 크기를 제한합니다. 제한이 없는 가상 머신은 이론상 예기치 않은 동작을 할 수 있으므로, 여유 메모리가 있는 시스템에서도 오류 메시지를 출력할 수 있습니다. 최적의 조합을 찾을 때까지 두 값을 조정해 가며 실험해 보는 것도 좋은 방법입니다.
참고로 이 문제는 실행 환경과 무관하게 발생할 수 있습니다. JVM은 GNU/Linux를 구동하는 데 사용되는 VM의 종류와 아무런 관련이 없기 때문입니다.
방법 2: 환경 변수를 내보내 변경 사항 영구 적용
작동하는 값을 찾았다면 export로 내보내 해당 세션에서 계속 유지되도록 설정할 수 있습니다. 예를 들어 bash 명령 프롬프트에서 export _JAVA_OPTIONS='-Xms256M -Xmx512M'을 실행하면, 서버에서 로그아웃할 때까지 별도의 옵션 없이 java 명령어만으로 실행할 수 있었습니다.
다만 새로운 세션에 로그인하면 설정이 초기화되므로, java 명령어를 자주 사용할 계획이라면 관련 시작 스크립트에 추가하는 것이 좋습니다. 실제로 .bash_login 파일에 해당 줄을 추가했더니, 로그인할 때마다 다시 입력하지 않아도 항상 잘 작동했습니다. 다른 셸을 사용한다면 그에 맞는 설정 파일을 찾아 추가해야 할 수도 있습니다.
특정 하드웨어 구성에서만 이 오류 메시지가 나타난다는 점을 눈치챘을 수도 있습니다. 그 이유는 이 오류가 대체로 물리적 RAM은 많지만 ulimit(메모리 사용 한도)가 낮게 설정된 시스템에서 발생하기 때문입니다. Java는 거대한 메모리 블록을 할당하려다 거부당하고, 이를 메모리 부족 상태로 해석하는 것입니다.
방법 3: 현재 Java 옵션 값 확인하기
명령줄에서 작업 중이며 현재 _JAVA_OPTIONS 값이 무엇으로 설정되어 있는지 빠르게 확인하고 싶다면, echo $_JAVA_OPTIONS를 실행하면 됩니다. 현재 설정된 값이 즉시 화면에 출력됩니다. 적절한 수치를 찾아가는 과정에서 문제를 진단할 때 매우 유용합니다.
이 수정 방법은 별도의 추가 작업이 필요하지 않지만, 실제로 가상 메모리가 부족한 상황이라면 Java는 여전히 "개체 힙을 위한 충분한 공간을 예약할 수 없습니다" 메시지를 출력합니다. 이 경우 현재 실행 중인 프로세스를 다시 점검하고, 가능하다면 서버를 재시작하는 것이 좋습니다. 스왑(swap) 공간을 늘리는 방법도 있지만, 이런 문제라면 일반적으로 다른 방식으로 근본 원인을 해결하는 편이 바람직합니다.
추가 팁: 64비트 Java 패키지 사용
드물게 설정이 모두 올바른데도 문제가 해결되지 않는다면, 64비트 Java 패키지가 설치되어 있는지 확인해 보세요. 64비트 버전은 이 문제에서 자유롭습니다. 연속된 메모리(contiguous memory) 요구 사항은 32비트 버전의 Java에만 적용되기 때문입니다. 일부 사례에서 64비트 버전이 32비트 가상 머신을 생성하려고 시도하는 경우를 발견했는데, 이때 명령줄에 -d64 옵션을 지정하면 문제가 해결되었습니다.