System.out.println을 실무에서 사용하면 안되는 이유

2024. 12. 5. 18:11·💻 Dev/Java & OOP
목차
  1. 왜일까?
  2. 1. 블로킹 I/O 작업
  3. 2. synchronized 작업
  4. + 로그 레벨관리가 어려움
  5. 해결 방법은?

자바를 접하게 되면 제일 먼저 하는 것이 System.out.println("Hello, World!")일 것이다.
그만큼 기초이자, 아주 많이 사용하는 코드이다.
하지만 System.out.println은 실무에서 절대 사용하지 말라고들 한다.

 

왜일까?

성능 이슈로는 크게 2가지가 있다. 블로킹 I/O작업을 한다는 점과 멀티스레드에서 락이 발생한다는 점이다.

 

1. 블로킹 I/O 작업

먼저 System 클래스의 static 변수인 out은 PrintStream 타입의 인스턴스이다.


      
public static final PrintStream out = null;

그리고 PrintStream 클래스는 java의 io 패키지 내에 있다.


      
package java.io;
public class PrintStream extends FilterOutputStream
implements Appendable, Closeable

즉, println()은 I/O 작업이며 이는 프로그램이 데이터를 출력할 때 운영체제(OS)의 표준 출력 장치(콘솔 창, 터미널)로 데이터를 보내는 작업을 수행한다는 뜻이다.

 

이는 Blocking I/O 방식으로 동작하며 이는 데이터 출력 작업이 완료될 때까지 호출한 스레드가 블록(block)되어 다른 작업을 처리하지 못하는 방식을 의미한다.

 

2. synchronized 작업

표준 출력(System.out)은 공유 자원이기 때문에 여러 스레드에서 동시에 접근할 경우 출력 순서가 뒤섞이거나 충돌할 가능성이 있다.
이를 방지하기 위해 println 내부에선 snychronized 를 사용해 동기화 처리한다.
(String 뿐만 아니라 다른 매개변수도 비슷하다.)


      
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}

synchronized은 한 번에 하나의 스레드만 자원을 사용할 수 있도록 제한한다.
따라서 멀티스레드 환경에서 다수의 스레드가 동시에 로그를 출력하려고 하면 대기 시간이 증가하고 병목 현상이 발생한다.

 

즉, System.out.println()이 끝날 때까지 아무 일도 할 수 없고 대기해야 하기에 오버헤드가 발생해 성능이 저하되는 것이다.

 

+ 로그 레벨관리가 어려움

System.out.println은 로그의 중요도(DEBUG, INFO, WARN, ERROR 등)를 구분하지 못한다. 이는 프로덕션 환경에서 디버깅 메시지와 중요한 오류 로그가 섞이는 문제를 야기할 수 있다.

 

 

해결 방법은?

실무에서는 Log4j, SLF4J 같은 전문 로깅 프레임워크를 사용하는 것이 일반적이다.
디버깅 및 모니터링에 더 효과적이기 때문이다.


이 도구들은 로그를 별도의 스레드에서 처리해 병목 현상을 최소화하고, 로그의 중요도를 구분해 출력할 수 있다.


      
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MyClass {
private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
public static void main(String[] args) {
logger.info("This is an INFO message.");
logger.debug("This is a DEBUG message.");
logger.error("This is an ERROR message.");
}
}

 

 

 

 

 

참고
System.out.println() 사용을 자제해야 하는 이유
System.out.println 메소드는 실무에서 절대 사용하지 마라.

저작자표시 비영리 (새창열림)

'💻 Dev > Java & OOP' 카테고리의 다른 글

자바는 왜 Lambda&Stream을 도입했을까? feat.함수형 프로그래밍  (0) 2024.12.26
리플렉션(Reflection)으로 DI 구현해보기 +단점  (0) 2024.12.22
Stack은 왜 상속의 실패 사례일까?  (0) 2024.12.12
가비지 컬렉터(GC)의 Roots  (0) 2024.12.04
Out-of-Memory(OOM)는 왜 발생하고, 어떻게 예방할까?  (0) 2024.11.30
instanceof 사용을 지양해야하는 3가지 이유  (0) 2024.11.29
  1. 왜일까?
  2. 1. 블로킹 I/O 작업
  3. 2. synchronized 작업
  4. + 로그 레벨관리가 어려움
  5. 해결 방법은?
'💻 Dev/Java & OOP' 카테고리의 다른 글
  • 리플렉션(Reflection)으로 DI 구현해보기 +단점
  • Stack은 왜 상속의 실패 사례일까?
  • 가비지 컬렉터(GC)의 Roots
  • Out-of-Memory(OOM)는 왜 발생하고, 어떻게 예방할까?
현주먹
현주먹
끄적끄적 개발.log
  • 현주먹
    현주먹의 개발로그
    현주먹
  • 전체
    오늘
    어제
    • 전체글 (162)
      • 👶🏻 CS (15)
        • Operating System (8)
        • Database (4)
        • Data Structure (2)
        • Software Engineering (1)
      • 💻 Dev (54)
        • Java & OOP (24)
        • Spring (4)
        • JPA (5)
        • Test Code (1)
        • Database (1)
        • JSP & Servlet (13)
        • Etc (6)
      • 💡 Algorithm (25)
        • 인프런 (9)
        • 백준 (16)
      • 🛠 DevOps & Tool (11)
        • Linux (4)
        • AWS (1)
        • Git (2)
        • Etc (4)
      • 📝 끄적끄적 (57)
        • 후기 및 회고 (5)
        • TDD, 클린 코드 with Java 17기 (3)
        • F-Lab (23)
        • 🖥️ 자바의 정석 (11)
        • 📖 Clean Code (3)
        • 항해99 코테 스터디 (11)
  • 블로그 메뉴

    • 🐈‍⬛ GitHub
    • TIL
  • 인기 글

  • 태그

    항해99
    백준10250
    자바의정석
    백준
    오블완
    코테스터디
    F-Lab
    개발자멘토링
    인프런 단어뒤집기
    jsp
    티스토리챌린지
    인프런 특정문자뒤집기
    til
    개발자취업
    에프랩
    JPA
    데브클럽
    99클럽
    ==와 equals()
    코딩테스트준비
    오라클
    객체지향
    NextSTEP
    TDD 클린 코드 with Java
    에프랩 후기
    자바의신절판
    f-lab 후기
    PostGreSQL함수
    C
    로또 미션
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
현주먹
System.out.println을 실무에서 사용하면 안되는 이유

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.