본문 바로가기

Programing/JVM(Java, Kotlin)

[JVM] PermGen?

자바로 프로그램을 짜다 운영(장시간)하다 보면 PermGen에 OutOfMemory라는 예외를 경험하게 된다.

보통 흔히 하는 대처로는 JVM 가동시에  XX:MaxPermSize=256m 같은 옵션을 주어 실행을 한다.


PermGen

PermGen은 Permanent Generation의 약자이다. 여기에 대해서는 jonthecollector가 2006년(!)에 작성한 글을 읽어보면 된다.

=> https://blogs.oracle.com/jonthecollector/entry/presenting_the_permanent_generation

요약하면 '클래스의 정의들과 연관된 메타데이터를 위해 사용되는 메모리 공간'정도가 될 것이다. permgen은 힙(young generation 과 tenured generation으로 나뉘어져 있는)으로 종종 착각되지만 힙의 일부가 아니다.


JVM은 기본적으로 64MB의 메모리 공간(PermGen)을 할당한다?

동작중인 JVM의 PermGen의 크기는 JRE 유틸리티인 jinfo.exe로 확인이 가능하다. (아래에서 6328은 pid이다)

>"C:\Program Files\Java\jre1.7\bin\jinfo.exe" -flag PermSize 6328

-XX:PermSize=21757952


샘플로 키보드 입력으로 block을 시키는 간단한 프로그램을 작성하고,

import java.io.*;


class HelloJava {

    public static void main(String[] args) throws IOException {

        System.out.println("Wait for line input from keyboard.");

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

String line = br.readLine();

System.out.println("You inputted: " + line);

    }

}

실행을 하고 확인을 해보니...


Copy & Paste를 위한 텍스트 대령이오~

>start java HelloJava

>tasklist /FI "IMAGENAME eq java.exe"

>"C:\Program Files\Java\jre1.7\bin\jinfo.exe" -flag PermSize 1296


영훈이가 근거없이 64MB가 기본이라고 적었으리라 생각하지 않지만..

김영훈이 보낸 공지 메일의 일부



찾아보니.. http://wiki.apache.org/tomcat/FAQ/Memory 에 보니 아래와 같은 글이 있었다.

If you have a lot of servlets or JSP's, you may need to increase your permanent generation. By default, it is 64MB. Quadrupling it to be -XX:MaxPermSize=256m might be a good start.


구글링을 더하다 보니 JVM에 따라 MaxPermGen의 크기가 변했음을 알 수 있었다.

<= http://www.freshblurbs.com/blog/2005/05/19/explaining-java-lang-outofmemoryerror-permgen-space.html

바로 위 홈페이지에 jsp로 메모리 테스트 하는 것이 있는데 에러가 나서 java로 빼보았다.

import java.lang.management.*;

import java.util.*;


class Memory {

    public static void main(String[] args) throws IOException {

List <MemoryPoolMXBean> mpmxb = ManagementFactory.getMemoryPoolMXBeans();

for (MemoryPoolMXBean item : mpmxb) {

System.out.println("Name:" + item.getName());

System.out.println("Type:" + item.getType());

System.out.println("Usage:" + item.getUsage());

System.out.println("Peak Usage:" + item.getPeakUsage());

System.out.println("Collection Usage:" + item.getCollectionUsage());

System.out.println("");

}

    }

}



http://xrath.com/javase/ko/6/docs/ko/api/java/lang/management/MemoryMXBean.html 가 이벤트 통지 구현이...