GC 로그가 충분하지 않아 Old 영역 증가, 정지시간, CSV 요청과 OOM의 인과관계는 추가 검증이 필요합니다. 아래 조치는 적용 후보이며, 이 글만으로 조치 완료나 전후 개선 효과가 입증된 것은 아닙니다.
1. 범위와 배경
원문 사례의 환경은 BIEE 10g, Presentation/OC4J, JDK 1.5.0_18(64-bit, sparcv9)입니다. 응답 지연과 메모리·CPU 증가가 함께 보고됐지만, 현재 확보된 글의 기록만으로 단일 원인을 확정할 수는 없습니다. 이 글은 당시 기록을 바탕으로 진단에 필요한 증거와 적용 조건을 정리합니다. 현재 지원 구성에 대한 안내는 아닙니다.
2. 환경 개요
원문에 제시된 경로는 Presentation의 $ORACLE_HOME/data/web/config/instanceconfig.xml, Scheduler의 $ORACLE_HOME/data/scheduler/config/instanceconfig.xml, Publisher의 두 xdo.cfg 위치입니다. 실제로 읽는 파일은 설치 구성과 시작 경로로 확인해야 하며, 두 파일의 존재만으로 모두 적용된다고 볼 수 없습니다. CMS/ParNew 옵션이 없다는 사실만으로 Serial GC를 단정할 수도 없습니다. JDK 5는 서버급 시스템에서 Throughput GC를 기본 선택할 수 있으므로 실제 JVM 옵션과 GC 로그를 대조해야 합니다.
-Xms6144m -Xmx6144m -XX:NewSize=2048m -XX:MaxNewSize=2048m -XX:SurvivorRatio=3
-XX:MaxPermSize=512m -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps \
-Xloggc:/u01b/.../oc4j_gc.log
# (UseConcMarkSweepGC / UseParNewGC 부재)
3. 타임라인
원문에 기록된 시간 흐름은 다음과 같습니다. 10시 20~29분 JVM RSS는 약 4.9GB였고, 10시 30분 전후 CSV 요청과 RSS 증가, CPU 약 50%가 보고됐습니다. 10시 37분~11시 17분에는 OOM 메시지 24회와 100MB 이상 CSV 시도가 기록돼 있습니다. 이는 이 글에 남은 사례 수치이며 이번 검토에서 원본 운영 로그를 재확인한 값은 아닙니다. 같은 시간대의 발생만으로 원인과 결과를 확정하지 않습니다.
4. 수집 데이터와 관측
RSS 증가와 OOM은 별도로 해석해야 합니다. 힙 사용량·세대별 점유량은 GC 로그로, 프로세스 메모리는 OS 지표로 확인합니다. 설정 키가 파일에 없다는 사실만으로 제한이 없거나 전량 메모리 처리라고 결론내릴 수 없습니다. 특히 InputStreamLimitInKB는 공식 10g 정정 문서에서 JavaHost config.xml의 XMLP 아래 설정으로 설명됩니다. 아래 예시의 Presentation ODBC 배치나 CSV 출력 크기 제한으로 해석하면 안 됩니다. 행·셀 제한과 Scheduler 설정도 해당 버전과 요청 경로를 확인해야 합니다.
5. 문제 정의
대용량 CSV 요청과 자원 증가, OOM이 같은 시간대에 나타난 것이 조사 출발점입니다. 객체 할당·승격과 GC 정지가 원인일 가능성은 있지만, 현재 기록으로 Old 영역 급증이나 장시간 Full GC를 확인했다고 말할 수는 없습니다. 요청 종류·동시성, 해당 프로세스의 GC 로그와 OOM 상세 메시지를 함께 분석해야 합니다.
6. 기술적 인과관계(RCA)
검증할 가설은 대형 결과셋 처리로 객체 할당이 늘고, 일부 객체가 오래 살아남아 GC 부담이나 OOM으로 이어졌는지입니다. 요청 시작·종료 시각, 처리한 프로세스, 세대별 점유량, GC 정지시간과 오류 시각을 대조해야 합니다. Broken pipe는 연결 종료의 증상일 수 있으므로 GC 또는 OOM의 직접 증거로 쓰지 않습니다.
7. 조치 후보와 적용 전 확인
먼저 요청 경로와 적용 버전을 확인하고, 비운영 환경에서 결과 제한·동시성 조절·배치 분산 후보를 검증합니다. 아래 XML은 원문 예시를 보존한 것으로 그대로 적용할 설정이 아닙니다. Presentation의 ODBC 아래 InputStreamLimitInKB 배치는 공식 JavaHost/XMLP 설명과 다르므로 적용하지 마세요. Publisher 속성의 지원 여부·적용 파일·기본값과 임시 저장소 사용도 별도 확인이 필요합니다.
파일: $ORACLE_HOME/data/web/config/instanceconfig.xml
원문 코드 보존 예시입니다. 적용 경로·속성·JDK 옵션의 지원 여부를 해당 릴리스에서 확인하기 전에는 실행하거나 설정에 붙여넣지 마세요. InputStreamLimitInKB는 JavaHost/XMLP 설정이며 이 예시의 ODBC 배치나 CSV 출력 한도로 사용하지 않습니다.
<ServerInstance>
<AnswerDetail>
<MaxRows>200000</MaxRows>
<MaxCells>3000000</MaxCells>
</AnswerDetail>
<ODBC>
<InputStreamLimitInKB>262144</InputStreamLimitInKB> <!-- 256MB -->
</ODBC>
</ServerInstance>
경로: $JAVA_HOME/jre/lib/xdo.cfg, $ORACLE_HOME/data/web/config/xdo.cfg
원문 코드 보존 예시입니다. 적용 경로·속성·JDK 옵션의 지원 여부를 해당 릴리스에서 확인하기 전에는 실행하거나 설정에 붙여넣지 마세요. InputStreamLimitInKB는 JavaHost/XMLP 설정이며 이 예시의 ODBC 배치나 CSV 출력 한도로 사용하지 않습니다.
<properties>
<property name="FOProcessingLimitInMemoryKB">262144</property> <!-- 256MB -->
<property name="system-temp-dir">/u01b/app/oracle/bi/10.1.3/data/tmp</property>
<property name="fo-chunk-size">5000000</property> <!-- 5MB -->
<property name="fo-trim-leading-whitespaces">true</property>
</properties>
원문 코드 보존 예시입니다. 적용 경로·속성·JDK 옵션의 지원 여부를 해당 릴리스에서 확인하기 전에는 실행하거나 설정에 붙여넣지 마세요. InputStreamLimitInKB는 JavaHost/XMLP 설정이며 이 예시의 ODBC 배치나 CSV 출력 한도로 사용하지 않습니다.
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps \
-Xloggc:/u01b/.../oc4j_gc.log
8. 효과 검증
요청 크기와 동시성이 비슷한 조건에서 응답시간·오류율·GC 정지·힙 점유·RSS·I/O를 각각 비교합니다. JavaHost XMLP 입력 제한을 CSV 출력 파일의 256MB 차단 기준으로 검증하면 안 됩니다. Publisher 임시 파일의 존재만으로 메모리 문제가 해결됐다고 볼 수도 없습니다. Broken pipe 변화는 클라이언트·프록시 연결 종료와 함께 분석하고, 개선 여부는 실제 전후 측정으로 판단합니다.
# Full GC 횟수
egrep -c 'Full GC' /u01b/.../oc4j_gc.log
# pause 통계
egrep -o '[0-9]+\.[0-9]+ secs\]' /u01b/.../oc4j_gc.log | tr -d ']' \
| awk '{s+=$1; if($1>m)m=$1} END{printf "count=%d avg=%.3fs max=%.3fs\n", NR, s/NR, m}'
9. 안정화 이후 고려할 일
먼저 실제 GC 종류와 세대별 사용량을 확인합니다. Parallel GC나 Adaptive 정책은 이미 사용 중일 수 있어 옵션 추가만으로 개선을 기대하지 않습니다. 힙 6→4GB 축소는 검증된 권장안이 아닙니다.
-XX:+UseParallelGC -XX:+UseAdaptiveSizePolicy -XX:ParallelGCThreads=<코어수> \
-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps \
-Xloggc:/u01b/.../oc4j_gc.log
10. JavaHost 관련 메모
CSV라는 출력 형식만으로 JavaHost나 OC4J를 원인 후보에서 제외하지 않습니다. 어떤 프로세스가 해당 요청을 처리했는지 요청 로그·프로세스 정보·오류 스택을 대조해야 합니다. EOFException도 원인 확정 근거가 아니며 발생한 서비스와 연결 상대를 확인해야 합니다. 프로세스 옵션 조회 방법은 플랫폼·JDK 버전·권한에 따라 달라지고, 이 글에서는 실제 서버 조회를 수행하지 않았습니다.
11. 리스크와 롤백 계획
가드레일과 스풀 제한을 적용하면 일부 대용량 내보내기가 차단될 수 있습니다.
업무상 불가피한 경우 예외 리스트를 운영하는 게 현실적입니다.
GC 로깅으로 I/O가 약간 늘 수 있으니 logrotate로 크기를 관리하고,
모든 변경은 백업과 원복 스크립트를 먼저 준비한 뒤 진행합니다.
12. 오픈 이슈와 체크리스트
남은 확인 사항은 요청을 처리한 프로세스와 실제 GC 정책, 설정 키의 릴리스별 지원 및 적용 파일, 제한값의 업무 영향입니다. 비운영 시험에서 로그·자원·응답 지표를 수집한 뒤 변경 범위와 원복 조건을 정합니다. 두 xdo.cfg에 일괄 적용하거나 GC 전환·힙 축소를 필수 단계로 취급하지 않습니다. 원본 장애 로그와 전후 시험 자료가 없으면 원인 확정과 개선 완료 판정은 보류합니다.
부록 A) 운영/검증 명령
원문 코드 보존 예시입니다. 적용 경로·속성·JDK 옵션의 지원 여부를 해당 릴리스에서 확인하기 전에는 실행하거나 설정에 붙여넣지 마세요. InputStreamLimitInKB는 JavaHost/XMLP 설정이며 이 예시의 ODBC 배치나 CSV 출력 한도로 사용하지 않습니다.
# 가드레일 존재 여부
grep -nE 'MaxRows|MaxCells|InputStreamLimitInKB' \
"$ORACLE_HOME/data/web/config/instanceconfig.xml"
# xdo.cfg 핵심 키(두 경로 모두)
for f in "$JAVA_HOME/jre/lib/xdo.cfg" "$ORACLE_HOME/data/web/config/xdo.cfg"; do
echo "== $f"
grep -nE 'FOProcessingLimitInMemoryKB|system-temp-dir|fo-chunk-size' "$f"
done
# GC 모드/적응 정책
jinfo -flags <OC4J_PID> | egrep 'UseParallelGC|UseConc|UseParNew|UseAdaptiveSizePolicy'
# Full GC 횟수
egrep -c 'Full GC' /u01b/.../oc4j_gc.log
# pause 통계
egrep -o '[0-9]+\.[0-9]+ secs\]' /u01b/.../oc4j_gc.log | tr -d ']' \
| awk '{s+=$1; if($1>m)m=$1} END{printf "count=%d avg=%.3fs max=%.3fs\n", NR, s/NR, m}'
부록 B) 설정 스니펫
원문 코드 보존 예시입니다. 적용 경로·속성·JDK 옵션의 지원 여부를 해당 릴리스에서 확인하기 전에는 실행하거나 설정에 붙여넣지 마세요. InputStreamLimitInKB는 JavaHost/XMLP 설정이며 이 예시의 ODBC 배치나 CSV 출력 한도로 사용하지 않습니다.
<ServerInstance>
<AnswerDetail>
<MaxRows>200000</MaxRows>
<MaxCells>3000000</MaxCells>
</AnswerDetail>
<ODBC>
<InputStreamLimitInKB>262144</InputStreamLimitInKB>
</ODBC>
</ServerInstance>
<properties>
<property name="FOProcessingLimitInMemoryKB">262144</property>
<property name="system-temp-dir">/u01b/app/oracle/bi/10.1.3/data/tmp</property>
<property name="fo-chunk-size">5000000</property>
<property name="fo-trim-leading-whitespaces">true</property>
</properties>
