본문 바로가기

CS/Java

(7)
가비지 컬렉션 프로그램을 개발하다 보면 유효하지 않은 메모리인 가비지(Garbage)가 발생한다. C언어를 사용하면 직접 메모리를 해제해주어야 한다. 하지만, Java나 Kotlin을 이용하면 개발자가 메모리를 직접 해제하는 일은 거의 없다. 그 이유는 JVM의 가비지 컬렉터(Garbage Collector)가 불필요한 메모리를 알아서 정리해 주기 때문이다. Java에서 명시적으로 불필요한 데이터를 표현하기 위해서는 null을 선언해 주면 된다. Person person = new Person(); person.setName("꽁탁"); person = null; // 가비지 발생 person = new Person(); person.setName("꽁탁2"); 위의 코드에서 기존의 "꽁탁"으로 생성된 person 객..
로깅 시 System.out.println()을 사용하지 않는 이유 System.out.println() 메서드는 자바 표준 출력이다. 하지만, 현업에서는 단순 디버깅 용도로도 System.out.println()을 사용하지 않는다고 한다. 휘발된다 System.out.println()은 표준 출력으로 사용한다. 즉, 파일로 저장되지 않고 휘발된다. 로그 파일로서 관리가 불가하여 문제를 기록하고 처리할 때, 로그를 확인할 수 없다. 에러 발생 시 추적할 수 있는 최소한의 정보가 남지 않는다 System.out.println()은 단순히 문자열을 출력하는 메서드이다. 따라서, 로깅 시 필요한 문제가 발생한 날짜, 시각, 문제의 수준, 위치 등 최소한의 정보가 기록되지 않는다. 이런 정보도 함께 인자로 전달하여 추적할 순 있지만, 매번 그런 정보를 일일이 남기는 작업은 번거..
new String()과 리터럴("") "꽁탁" != new String("꽁탁"); new String() new String()은 new 키워드로 새로운 객체를 생성하기 때문에 Heap 메모리에 새로운 주소를 할당받는다. 따라서, 모든 String 변수의 주소가 다르게 저장된다. String a = "ABC"; //in String Constant Pool String b = new String("ABC"); //in Heap String c = new String("ABC"); //in Heap System.out.println(a == b || a == c); // false String 리터럴 문자열 리터럴은 Heap 내의 String Constant Pool이라는 영역에 할당된다. 만약, 이미 같은 값을 가지고 있는 리터럴이 Con..
String, StringBuffer, StringBuilder 자바에서 문자열을 다루는 자료형 클래스로 String, StringBuffer, StringBuilder가 있다. String은 불변의 속성을 가지며, StringBuffer와 StringBuilder는 가변의 속성을 가진다. String 자바에서 String 객체의 값은 변경할 수 없다. public final class String implements java.io.Serializable, Comparable { private final byte[] value; } String의 내부 구성 요소는 위와 같은데, 상수(final)형으로 선언되어 있어 변경할 수 없다. String str = "hello"; str = str + " world"; System.out.println(str); // hell..
equals()와 hashCode() 자바의 모든 클래스는 Object 클래스를 상속받는다. Object 클래스에는 equals()와 hashCode()라는 메서드가 선언되어 있어, 모든 클래스는 equals()와 hashCode()를 상속받는다. equals() equals() 메서드는 어떤 두 객체가 동일한지 비교할 때 사용한다. 이는 동일성(Identity)을 비교하는 것이다. 즉, 두 객체가 동일한 메모리 주소일 경우에만 동일한 객체가 된다. 하지만, 프로그래밍 상에서 같은 값을 가지는 객체를 같은 객체로 인식해야 하는데, 이러한 동등성(Equality)을 위해 equals() 메서드를 오버라이딩 해야 한다. String name1 = new String("꽁탁"); String name2 = new String("꽁탁"); Syst..
Java 컴파일 과정 Java는 JVM(Java Virtual Machine)으로 인해 OS에 독립적인 특징을 가진다.그렇다면 JVM의 어떠한 기능 때문에 OS에 독립적으로 실행시킬 수 있는지 자바 컴파일 과정을 통해 알아보자.)자바 컴파일 순서개발자가 자바 소스 코드(.java)를 작성한다.자바 컴파일러가 자바 소스 코드(.java) 파일을 읽어 바이트 코드(.class)로 변경한다.바이트 코드는 아직 컴퓨터가 읽을 수 없는, JVM이 읽을 수 있는 코드이다.컴파일된 바이트 코드를 클래스 로더(Class Loader)에게 전달한다.클래스 로더는 동적 로딩(Dynamic Loading)을 통해 필요한 클래스들을 로딩 및 링크하여 런타임 데이터 영역(Runtime Data Area), 즉 JVM의 메모리에 올린다.실행 엔진(E..
직렬화(Serialization) SSAFY 프로젝트를 진행하면서 몇몇 클래스에 Serializable 인터페이스를 상속하였는데, 이번 기회에 직렬화에 대해 자세히 알아보자. 개발을 진행하다 보면 다음과 같은 상황이 발생한다. - 생성한 객체나 데이터를 파일로 저장한다. - 저장한 객체나 데이터를 읽어온다. - 다른 서버에서 생성한 객체나 데이터를 받아온다. 우리가 생성한 객체나 데이터를 파일로 읽거나 쓸 때, 다른 서버로 보내거나 받을 때 직렬화가 꼭 필요하다. 직렬화는 왜 필요할까? 대부분의 OS의 프로세스 구현은 서로 다른 가상 메모리 주소 공간을 갖기 때문에 Object 타입의 참조값(주소값)을 전달한다면 사용할 수 없다. 때문에 서로 다른 메모리 공간 사이의 데이터 전달을 위해서는 주소값이 아닌 Byte 형태로 직렬화(변환)된 ..