반응형
더 얻은 내용
-
- call by ~ 들 정리해보기
- 자바는 참조값을 복사 전달하므로 배열이든 List든(원시타입이든 객체든) 원본이 변경됨
- 자바는 포인터를 사용하지 않아서 메모리 안전성이 높음
- 만약 자바도 포인터로 메모리를 조작할 수 있었다면, GC 처리된 자원에 대해 바뀌거나 사라진 메모리 주소를 바라볼 수도 있음. 그래서 포인터를 사용하지 않을 수도.
- 포인터에 대한 압박 → 개발 생산성 저하 → Java 가 기업단에서 우세하게 된 배경일 수도.
- C의 댕글링 포인터 : 이미 해제된(free 또는 delete된) 메모리를 계속 가리키고 있는 포인터
- atomic은 어떻게 atomic 을 보장하는가?
- call by ~ 들 정리해보기
기억에 남는 내용
- 아래 세가지 내용이 자바가 객체지향 언어라는 점을 조금더 실감나게 해줌
- 자바에서 클래스를 떠나 존재할 수 있는 건 없음
- 제어문은 메서드 안에만 존재할 수 있음
- 메서드 간 소통은 오직 인자와 반환값을 통해서만 일어남 (메서드의 블랙박스화)
- 자바는 항상 Call By Value 이다
- 객체를 전달할 때 : 객체의 참조값(주소)를 Call By Value 로 전달함처음 전달받은 원본 객체는 영향을 받지 않음
→ 그래서 전달받은 객체 변수에 다른 객체를 할당하면 참조값이 변경됨 - 원시타입을 전달할 때 : 항상 Call By Value!
- 객체를 전달할 때 : 객체의 참조값(주소)를 Call By Value 로 전달함처음 전달받은 원본 객체는 영향을 받지 않음
- 자바는 어떻게 포인터 없이 동작이 가능한가?
- 포인터 대신 객체 참조를 통해 접근
- 변수 체는 스택에 저장되어 객체의 참조값(주소값)을 저장. 객체는 힙에 저장.
- 더이상 참조되지 않는 객체는 GC가 힙에서 회수
→ 추후 GC 에 대해 더 자세히..
자바 .java → 기계어 컴파일 및 변환 과정
- 단계 : 컴파일러에 의해 컴파일 → JVM에 의해 기계어로 변환 후 JRE 환경에서 실행
1. 자바 소스코드 (.java)
- 자바 컴파일러(javac)에 의해 자바 목적파일로 컴파일
- .java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
2. 자바 byte code (목적파일과 유사한 역할, .class)
- JVM 이 실행할 수 있는 형태
- JVM명령어(opcode)로 구성됨
- JVM 에서 기계어로 변환 후 실행
- 16비트 바이너리 코드 .class 의 어셈블리어 형태 (javap -c HelloWorld.class 출력 결과)
Compiled from "HelloWorld.java"
public class HelloWorld {
public HelloWorld();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Hello, World!
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
3. 기계어
- 자바 목적파일을 JVM 에서 기계어 변환 후 실행
- 인터프리팅 or JIT(Just-In-Time) 컴파일러로 기계어 변환
- 실제로 CPU 에서 실행되는 형태
- 기계어(바이너리 코드)를 x86-64 아키텍쳐 어셈블리어로 표현한 것 (일부)
mov rdi, OFFSET FLAT:.LC0 ; "Hello, World!" 문자열 로드
call printf ; printf 함수 호출 (C 라이브러리 사용)
궁금증
- static 변수(상수x)는 왜 존재할까? 언제 필요할까?
- 프로그램이 종료되지 않는 이상 메모리에 계속 남아있음
- 프로그램 전체에 공유해야할 값..? 그런데 이제 여러 스레드에서 접근해서 값을 변경해도 괜찮은.. 그런 게 존재하나
- 변경되지 않는 값이면 static 상수를 쓰면 되니 해당 안됨
- DB 커넥션 풀을 관리에 쓰일 수 있지 않을까? → 싱글톤이 필요한 것에 더 가까울 듯?
- 게임 서버에서 캐릭터의 HP같은 속성 기본값을 static 으로 쓰더라
- JVM 은 바이트코드 실행 방법(인터프리팅/JIT컴파일)을 언제 어떻게 결정할까?
- JVM 내부 실행엔진이 둘 중 어떤 방식으로 실행할 지 결정
- 코드 실행 횟수 : 처음엔 인터프리팅 모드로 실행. 실행횟수에 따라 내부 카운터로 핫스팟 감지 (보통 10,000회 실행 시 JIT 컴파일 대상)
- 그 외 CPU 성능 및 메모리, 코드 실행 시간, JVM 옵션에 따라 등에 의해 결정
- 실행 방법을 강제해줘야하는 상황은 어떤 게 있을까?
- JVM 내부 실행엔진이 둘 중 어떤 방식으로 실행할 지 결정
읽으며 정리 기록
1장
- 어셈블리어 :
- 기계어와 니모닉을 1대1 매칭한 어셈블리어(니모닉)
- 기계어를 벗어나 인간의 언어를 모방
- C 언어 : 싱글소스. 이식성 ↑. One Source (Multi Object) Use Anywhere
- C++ : 객체지향 지원
- 자바
- 객체지향을 위해 태어난 언어. 클래스를 떠나 존재할 수 있는 건 없음.
- 포인터없는 프로그래밍
- 가상머신(JVM). 이식성 ↑. Write Once Use Anywhere
- JDK + JRE [ JVM ]
- 스프링은 OOP 프레임워크이다.
- 스프링은 PSA 기법을 통해 중구난방으로 구현된 다양한 기술을 표준화된 방식으로 사용할 수 있게 지원해준다.
2장
- JRE
- JVM 을 위한 실행 환경
- 호스트 OS와 JVM 간의 추상화 계층 역할. JVM이 OS 기능을 간접적으로 활용할 수 있게 해줌
- OS 의 기능을 사용할 수 있는 Java 라이브러리 제공
- 네이티브 코드와 상호작용할 수 있는 인터페이스 제공
- JVM 의 메모리 관리, GC 기능, 스레드 관리 등을 처리해줌
- 자바의 메모리 사용방식 (T구조)
- 코드 실행 영역 / 데이터 저장 영역
- 데이터 저장 영역
- 스태틱 static : 클래스(패키지)가 올라가는 곳
- 스택 stack : 실행할 메서드 ‘’
- 힙 heap : 객체 ‘’
- 메서드를 여는 중괄호를 만날 때마다 스택 영역에 메서드를 실행할 스택 프레임이 생김. 아래부터 메모리를 사용함. 닫는 중괄호를 만나면 스택 프레임이 소멸함
- 메서드 안에서 또다른 중괄호(if문 등)를 만나면 해당 메서드의 스택 프레임 내부에 또다른 스택 프레임이 생성되고, 사용된 후 닫는 중괄호를 만나면 소멸한다.
- 내부 블록(스택프레임)에서 외부 블록의 데이터에 접근할 수는 있지만,
- 역은 불가능함
- 힙 영역의 객체 멤버 변수들은 GC에 의해 회수됨
- 메서드의 블랙박스화 : 메서드들은 인자와 반환값으로만 소통함
- 멀티 스레드 / 멀티 프로세스
- 멀티 스레드 : 스택영역 구분, 스태틱과 힙 영역 공유
→ 특히 멀티 스레드 환경에서는 전역변수 사용하지 말 것. 스레드 안정성 깨짐 - 멀티 프로세스 : 모든 영역 별도사용 (각자의 T메모리 사용)
- 멀티 스레드 : 스택영역 구분, 스태틱과 힙 영역 공유
반응형
'Java' 카테고리의 다른 글
[🐸객체 개구리책] 4,5장 자바가 확장한 객체지향 & SOLID (0) | 2025.03.19 |
---|---|
[🐸객체 개구리책] 3장 자바와 객체지향 (0) | 2025.03.18 |
반응형
더 얻은 내용
-
- call by ~ 들 정리해보기
- 자바는 참조값을 복사 전달하므로 배열이든 List든(원시타입이든 객체든) 원본이 변경됨
- 자바는 포인터를 사용하지 않아서 메모리 안전성이 높음
- 만약 자바도 포인터로 메모리를 조작할 수 있었다면, GC 처리된 자원에 대해 바뀌거나 사라진 메모리 주소를 바라볼 수도 있음. 그래서 포인터를 사용하지 않을 수도.
- 포인터에 대한 압박 → 개발 생산성 저하 → Java 가 기업단에서 우세하게 된 배경일 수도.
- C의 댕글링 포인터 : 이미 해제된(free 또는 delete된) 메모리를 계속 가리키고 있는 포인터
- atomic은 어떻게 atomic 을 보장하는가?
- call by ~ 들 정리해보기
기억에 남는 내용
- 아래 세가지 내용이 자바가 객체지향 언어라는 점을 조금더 실감나게 해줌
- 자바에서 클래스를 떠나 존재할 수 있는 건 없음
- 제어문은 메서드 안에만 존재할 수 있음
- 메서드 간 소통은 오직 인자와 반환값을 통해서만 일어남 (메서드의 블랙박스화)
- 자바는 항상 Call By Value 이다
- 객체를 전달할 때 : 객체의 참조값(주소)를 Call By Value 로 전달함처음 전달받은 원본 객체는 영향을 받지 않음
→ 그래서 전달받은 객체 변수에 다른 객체를 할당하면 참조값이 변경됨 - 원시타입을 전달할 때 : 항상 Call By Value!
- 객체를 전달할 때 : 객체의 참조값(주소)를 Call By Value 로 전달함처음 전달받은 원본 객체는 영향을 받지 않음
- 자바는 어떻게 포인터 없이 동작이 가능한가?
- 포인터 대신 객체 참조를 통해 접근
- 변수 체는 스택에 저장되어 객체의 참조값(주소값)을 저장. 객체는 힙에 저장.
- 더이상 참조되지 않는 객체는 GC가 힙에서 회수
→ 추후 GC 에 대해 더 자세히..
자바 .java → 기계어 컴파일 및 변환 과정
- 단계 : 컴파일러에 의해 컴파일 → JVM에 의해 기계어로 변환 후 JRE 환경에서 실행
1. 자바 소스코드 (.java)
- 자바 컴파일러(javac)에 의해 자바 목적파일로 컴파일
- .java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
2. 자바 byte code (목적파일과 유사한 역할, .class)
- JVM 이 실행할 수 있는 형태
- JVM명령어(opcode)로 구성됨
- JVM 에서 기계어로 변환 후 실행
- 16비트 바이너리 코드 .class 의 어셈블리어 형태 (javap -c HelloWorld.class 출력 결과)
Compiled from "HelloWorld.java"
public class HelloWorld {
public HelloWorld();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Hello, World!
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
3. 기계어
- 자바 목적파일을 JVM 에서 기계어 변환 후 실행
- 인터프리팅 or JIT(Just-In-Time) 컴파일러로 기계어 변환
- 실제로 CPU 에서 실행되는 형태
- 기계어(바이너리 코드)를 x86-64 아키텍쳐 어셈블리어로 표현한 것 (일부)
mov rdi, OFFSET FLAT:.LC0 ; "Hello, World!" 문자열 로드
call printf ; printf 함수 호출 (C 라이브러리 사용)
궁금증
- static 변수(상수x)는 왜 존재할까? 언제 필요할까?
- 프로그램이 종료되지 않는 이상 메모리에 계속 남아있음
- 프로그램 전체에 공유해야할 값..? 그런데 이제 여러 스레드에서 접근해서 값을 변경해도 괜찮은.. 그런 게 존재하나
- 변경되지 않는 값이면 static 상수를 쓰면 되니 해당 안됨
- DB 커넥션 풀을 관리에 쓰일 수 있지 않을까? → 싱글톤이 필요한 것에 더 가까울 듯?
- 게임 서버에서 캐릭터의 HP같은 속성 기본값을 static 으로 쓰더라
- JVM 은 바이트코드 실행 방법(인터프리팅/JIT컴파일)을 언제 어떻게 결정할까?
- JVM 내부 실행엔진이 둘 중 어떤 방식으로 실행할 지 결정
- 코드 실행 횟수 : 처음엔 인터프리팅 모드로 실행. 실행횟수에 따라 내부 카운터로 핫스팟 감지 (보통 10,000회 실행 시 JIT 컴파일 대상)
- 그 외 CPU 성능 및 메모리, 코드 실행 시간, JVM 옵션에 따라 등에 의해 결정
- 실행 방법을 강제해줘야하는 상황은 어떤 게 있을까?
- JVM 내부 실행엔진이 둘 중 어떤 방식으로 실행할 지 결정
읽으며 정리 기록
1장
- 어셈블리어 :
- 기계어와 니모닉을 1대1 매칭한 어셈블리어(니모닉)
- 기계어를 벗어나 인간의 언어를 모방
- C 언어 : 싱글소스. 이식성 ↑. One Source (Multi Object) Use Anywhere
- C++ : 객체지향 지원
- 자바
- 객체지향을 위해 태어난 언어. 클래스를 떠나 존재할 수 있는 건 없음.
- 포인터없는 프로그래밍
- 가상머신(JVM). 이식성 ↑. Write Once Use Anywhere
- JDK + JRE [ JVM ]
- 스프링은 OOP 프레임워크이다.
- 스프링은 PSA 기법을 통해 중구난방으로 구현된 다양한 기술을 표준화된 방식으로 사용할 수 있게 지원해준다.
2장
- JRE
- JVM 을 위한 실행 환경
- 호스트 OS와 JVM 간의 추상화 계층 역할. JVM이 OS 기능을 간접적으로 활용할 수 있게 해줌
- OS 의 기능을 사용할 수 있는 Java 라이브러리 제공
- 네이티브 코드와 상호작용할 수 있는 인터페이스 제공
- JVM 의 메모리 관리, GC 기능, 스레드 관리 등을 처리해줌
- 자바의 메모리 사용방식 (T구조)
- 코드 실행 영역 / 데이터 저장 영역
- 데이터 저장 영역
- 스태틱 static : 클래스(패키지)가 올라가는 곳
- 스택 stack : 실행할 메서드 ‘’
- 힙 heap : 객체 ‘’
- 메서드를 여는 중괄호를 만날 때마다 스택 영역에 메서드를 실행할 스택 프레임이 생김. 아래부터 메모리를 사용함. 닫는 중괄호를 만나면 스택 프레임이 소멸함
- 메서드 안에서 또다른 중괄호(if문 등)를 만나면 해당 메서드의 스택 프레임 내부에 또다른 스택 프레임이 생성되고, 사용된 후 닫는 중괄호를 만나면 소멸한다.
- 내부 블록(스택프레임)에서 외부 블록의 데이터에 접근할 수는 있지만,
- 역은 불가능함
- 힙 영역의 객체 멤버 변수들은 GC에 의해 회수됨
- 메서드의 블랙박스화 : 메서드들은 인자와 반환값으로만 소통함
- 멀티 스레드 / 멀티 프로세스
- 멀티 스레드 : 스택영역 구분, 스태틱과 힙 영역 공유
→ 특히 멀티 스레드 환경에서는 전역변수 사용하지 말 것. 스레드 안정성 깨짐 - 멀티 프로세스 : 모든 영역 별도사용 (각자의 T메모리 사용)
- 멀티 스레드 : 스택영역 구분, 스태틱과 힙 영역 공유
반응형
'Java' 카테고리의 다른 글
[🐸객체 개구리책] 4,5장 자바가 확장한 객체지향 & SOLID (0) | 2025.03.19 |
---|---|
[🐸객체 개구리책] 3장 자바와 객체지향 (0) | 2025.03.18 |