본문 바로가기

Java 기본 문법 - 참조 서적 [이것이 자바다 - 한빛미디어]/9. 기본 API 클래스

5. Java 자바 [API] - System 클래스

System 클래스

 

바 프로그램은 운영체제 상에서 바로 실행되는 것이 아니라 JVM 위에서 실행된다.

따라서 운영체제의 모든 기능을 자바 코드로 직접 접근하기 어렵다.

 

하지만, java.lang 패키지에 속하는 System 클래스를 활용하면 운영체제의 일부 기능을 이용할 수 있다.

프로그램 종료, 키보드로 부터 입력, 모니터로 출력, 메모리 정리, 현재 시간 읽기, 시스템 프로퍼티 읽기, 환경 변수 읽기 등이 가능하다.

 

System 클래스의 모든 필드와 메소드는 정적(static) 필드와 정적(static)메소드로 구성되어 있다.

 

System 클래스의 메소드들 


1. 프로그램 종료 exit()

 

강제적으로 JVM을 종료시킬 필요가 있을 때 exit() 메소드를 호출한다.

exit() 메소드는 현재 실행하고 있는 프로세스를 강제 종료시키는 역할을 한다.

 

exit() 메소드는 int 매개값을 지정하도록 되어있다. (종료 상태값)

일반적으로 정상 종료일 경우 0 으로 지정하고, 비 정상 종료일 경우 0 이외의 다른 값을 준다.

 

System.exit(0);    // 정상 종료

 

어떤 값을 주더라도 종료가 되지만, 만약 특정 값이 입력된 경우에만 종료하고 싶다면

자바의 보안 관리자를 직접 설정해서 종료 상태값을 확인하면 된다.

 

System.exit()이 실행되면 보안 관리자의 checkExit() 메소드가 자동 호출되는데,

이 메소드에서 종료 상태값을 조사해서 특정 값이 입력되지 않으면 SecurityException 을 발생시켜서 System.exit() 을 호출한 곳에서 예외 처리를 할 수 있도록 한다.

 

checkExit() 이 정상적으로 실행되면 JVM은 종료된다.

 

예) 값으로 5가 입력되면 JVM 을 종료하도록 보안 관리자 설정

 

System.setSecurityManager(new SecurityManager() {

    @Override

    public void checkExit(int status) {

        if(status != 5) {

            throw new SecurityException();

        }

    }

});

 

예) ExitExample.java

종료 상태 값이 5일 경우에만 프로세스 종료, 5가 아니면 보안 관리자에서 SecurityException 을 발생시키고

예외 처리를 한다. for 문은 정상적으로 계속 실행 상태를 유지하게 된다.

 

public class ExitExample {
    public static void main(String[] args) {
        // 보안 관리자 설정
        System.setSecurityManager(new SecurityManager() {
            @Override
            public void checkExit(int status) {
                if(status != 5) {
                    throw new SecurityException();
                }
            }
        });

        for(int i = 0; i < 10; i++) {
            // i값 출력
            System.out.println(i);
            try {
                //JVM 종료 요청
                System.exit(i);
            } catch(SecurityException e) {  }
        }
    }
}

 

 


2. 쓰레기 수집기 실행 gc()

 

자바에서 메모리는 JVM이 알아서 자동으로 관리한다.

JVM은 메모리가 부족할 때, CPU가 한가할 때 “쓰레기 수집기(Garbage Collector)”를 실행시켜서

사용하지 않는 객체를 자동으로 제거한다.

 

예) new 연산자로 Car 객체를 생성하고 변수 myCar에 객체 번지를 대입했을 경우

 

Car myCar = new Car();

 

만약 myCar에 null을 대입하면 myCar는 객체의 번지를 잃게 된다.

객체의 번지를 모르기 때문에 더 이상 Car 객체는 사용할 수 없고 쓰레기가 되어버린다.

 

myCar = null;

 

변수 myCar 가 다른 Car 객체를 참조하는 경우도 마찬가지이다.

이전 객체의 번지를 잃어버리기 때문에 이전 객체는 쓰레기가 되어버린다.

 

Car myCar = new Car();      // 이전 참조 객체 (쓰레기 객체가 되어버림)

myCar = new Car();             // 현재 참조 객체 (새로운 Car 객체를 참조하게 된다.)

 

쓰레기 객체가 되어버린다.

 

쓰레기 수집기는 개발자가 직접 코드로 실행할 수 없고,

JVM에게 가능한 빨리 실행해 달라고 요청할 수 있다. 요청 = System.gc() 메소드가 호출되면

쓰레기 수집기가 바로 실행되지 않고 JVM 은 빠른 시간 내에 실행시키기 위해 노력한다.

 

System.gc();

 

쓰레기가 생길 때마다 쓰레기 수집기가 동작한다면,

수행해야 될 프로그램의 속도가 떨어지기 때문에 성능 측면에서 좋지 않다.

메모리가 충분하다면 굳이 쓰레기 수집기를 실행할 필요가 없다.

 

 

쓰레기 수집기가 객체를 삭제하는지 확인하기 위해 객체 소멸자 finalize() 를 이용한다.

쓰레기 수집기는 객체를 삭제하기 전에 마지막으로 객체 소멸자를 실행한다.

 

 

예) GcExample.java : gc 메소드

 

public class GcExample {
    public static void main(String[] args) {
        Employee emp;

        emp = new Employee(1);   // 쓰레기 객체가 됨
        emp = null;
        emp = new Employee(2);    // 쓰레기 객체가 됨
        emp = new Employee(3);

        System.out.print(“emp 가 최종적으로 참조하는 사원 번호 : ”);
        System.out.println(emp.eno);
        System.gc();     // 쓰레기 수집기 실행 요청
    }
}

class Employee {
    public int eno;

    public Employee(int eno) {
        this.eno = eno;
        System.out.println(“Employee (” + eno + “) 가 메모리에 생성됨”);
    }

    public void finalize() {   // 소멸자
        System.out.println(“Employee (” + eno + “) 가 메모리에서 제거됨”);
    }
}

3. 현재 시각 읽기 currentTimeMillis(), nanoTime()

 

System 클래스의 currentTimeMillis() 메소드, nanoTime() 메소드는

컴퓨터의 시계로부터 현재 시간을 읽어서

밀리세컨드(1 / 1000 초) 단위와 나노세컨드(1 / 109 초) 단위의 long 값을 리턴한다.

 

long time = System.currentTimeMillis();

long time = System.nanoTime();

 

리턴된 값은 주로 프로그램의 실행 소요 시간 측정에 사용된다.

프로그램 시작 시 시각을 읽고, 프로그램 끝날 때 시각을 읽어서 차이를 구하면 실행 소요 시간이 나온다.

 

예) SystemTimeExample.java : 프로그램 소요 시간 구하기

 

public class SystemTimeExample {
    public static void main(String[] args) {
        long time1 = System.nanoTime();      // 시작 시간 읽기

        int sum = 0;
        for(int i = 1; i <= 1000000; i++) {
            sum += 1;
        }

        long time2 = System.nanoTime();     // 끝 시간 읽기

        System.out.println(“1 ~ 1000000 까지의 합 : ”+ sum);
        System.out.println(“계산에 ” + (time2 – time1) + “나노 초가 소요됨”);
    }
}

 

 


4. 시스템 프로퍼티 읽기 getProperty()

 

JVM 이 시작할 때 자동 설정되는 시스템의 속성값을 말한다.

예를 들어 운영체제의 종류 및 자바 프로그램을 실행시킨 사용자 아이디, JVM 버전,

운영체제에 사용되는 파일 경로 구분자 등이 있다.

 

시스템 프로퍼티는 키(key)와 값(value)으로 구성되어 있다.

 

키(key)

설명

값(value)

java.version

자바의 버전

1.8.0_20

java.home

사용하는 JRE 의 파일 경로

<jdk 설치경로> \ jre

os.name

OS System 이름

Windows 10

file.separator

파일 구분자 (“/” on Unix)

\

user.name

사용자의 이름

사용자의 계정

user.home

사용자의 홈 디렉토리

C:\Users\사용자계정

user.dir

사용자가 현재 작업 중인 디렉토리 경로

다양

 

System.getProperty() 메소드로 시스템 프로퍼티를 읽어올 수 있다.

시스템 프로퍼티의 키 이름을 매개값으로 받고, 해당 키에 대한 값을 문자열로 리턴한다.

 

String value = System.getProperty(String key);

 

예) GetPropertyExample.java : 시스템 프로퍼티 읽기

 

public class GetPropertyExample {
    public static void main(String[] args) {
        String osName = System.getProperty(“os.name”);
        String userName = System.getProperty(“user.name”);
        String userHome = System.getProperty(“user.home”);

        System.out.println(“운영체제 이름 : ” + osName);    // 개별 속성 읽기
        System.out.println(“사용자 이름 : ” + userName);
        System.out.println(“사용자 홈디렉토리 : ” + userHome);

        System.out.println(“==========================”);
        System.out.println(“[key]   value”);
        System.out.println(“==========================”);

        Properties props = System.getProperties();
        Set keys = props.keySet();

        for(Object objKey : keys) {  // 모든 속성의 키와 값을 출력
            String key = (String) objKey;
            String value = System.getProperty(key);
            System.out.println(“ [ ” + key + “ ] ” + value);
        }
    }
}

 

System.getProperties() 메소드는 모든(키, 값) 쌍을 저장하고 있는 Properties 객체를 리턴 한다.

이 객체의 keySet() 메소드를 호출하면 키만 구성된 Set 객체를 얻을 수 있다.

 

for 문은 Set 객체로부터 키를 하나씩 얻어내어 문자열로 변환한 다음,

System.getProperty() 메소드로 값을 얻어 키와 값을 모두 출력한다.

 


5. 환경 변수 읽기 getenv()

 

대부분의 운영체제는 실행되는 프로그램들에게 유용한 정보를 제공할 목적으로 환경 변수를 제공한다.

 

환경 변수 : 프로그램상의 변수가 아니라 운영체제에서 이름(Name)과 값(value)으로 관리되는 문자열 정보이다.

 

운영체제가 설치될 때 기본적인 내용이 설정되고,

사용자가 직접 설정하거나 응용 프로그램이 설치될 때 자동적으로 추가 설정되기도 한다.

 

자바 프로그램에서는 환경 변수의 값이 필요한 경우, System.getenv() 메소드를 사용한다.

매개값으로 환경 변수 이름을 주면 값을 리턴한다.

 

String value = System.getenv(String name);

 

예) SystemEnvExample.java : JAVA_HOME 환경 변수의 값을 얻어와서 출력하기

 

public class SystemEnvExample {
    public static void main(String[] args) {
        String javaHome = System.getenv(“JAVA_HOME”);
        System.out.println(“JAVA_HOME : ” + javaHome);
    }
}