Object Internals 앞선 글에서는 Python의 모든 값이 객체로 표현된다는 Object Model과 이러한 객체를 위한 메모리를 CPython이 어떻게 할당하고 회수하는지 살펴보았습니다. 이번에는 두 내용을 연결해 실제 Python 객체가 CPython 내부의 메모리에서 어떤 모습으로 존재하는지 살펴보겠습니다. a = 10b = [1, 2, 3]c = {"name": "Python"}Python 언어 수준에서는 10, [1, 2, 3], {"name": "Python"} 모두 객체입니다. 하지만 실제 CPython 내부에서는 각각 다른 C 구조를 사용합니다. 이들 객체는 서로 다른 데이터를 저장하지만 CPython이 모든 객체를 동일한 방식으로 다룰 수 있도록 공통적인 구조 역시 가지고 있습..
Memory Management 앞선 글에서는 Python 코드가 Code Object와 Bytecode로 변환되고, Execution Frame과 Bytecode Interpreter를 통해 실행되는 과정을 살펴보았습니다. 그 과정에서 Python은 계속해서 새로운 객체를 생성하고 사용합니다.a = 10users = []name = "Python"위 코드의 10, [], "Python"은 모두 Python 객체입니다. 그렇다면 이러한 객체를 저장할 메모리는 어디에서 가져오고 더 이상 사용하지 않는 객체의 메모리는 언제 회수될까요? Python의 Memory Management는 크게 두 가지 관점으로 나누어볼 수 있습니다. CPython에서는 Python Memory Manager와 전용 Memory ..
Data Model 앞선 글에서는 Python에서 모든 데이터가 Object로 표현되고, Name이 Object에 Binding되는 구조와 Python 코드가 Bytecode와 Execution Frame을 통해 실행되는 과정을 살펴보았습니다. 이번에는 조금 다른 관점에서 Python 객체를 살펴보겠습니다.a.foo()value = d["name"]length = len(a)result = a + b위 코드는 모두 익숙한 Python 문법이지만 객체가 어떤 규칙에 따라 이러한 문법에 참여하는지는 단순하지 않습니다. Python은 이러한 객체의 동작을 Data Model이라는 일관된 규칙으로 정의합니다. 이번 글에서는 Attribute Lookup, Function과 Method, Descriptor, M..
Execution Model 앞서 Object Model에서는 Python의 변수와 객체를 다음과 같은 관계로 살펴보았습니다. 그렇다면 Python은 이 코드를 어떻게 실행할까요? Python은 소스 코드를 CPU가 직접 실행하도록 전달하지 않습니다. CPython에서는 Python 소스를 컴파일하여 Bytecode를 만들고 이를 실행하기 위한 Frame을 구성한 뒤 Bytecode Interpreter가 명령을 하나씩 처리합니다. 전체적인 흐름은 다음과 같습니다. 이번 글에서는 Python의 Execution Model을 중심으로 Compiler, Code Object, Bytecode, Frame, Call Stack 그리고 CPython Runtime의 관계를 살펴보겠습니다. Compiler P..
Object Model Python의 변수를 처음 배울 때 다음과 같은 코드를 흔히 "a라는 변수에 10이라는 값을 저장한다"고 설명합니다.a = 10 입문 단계에서는 충분히 직관적인 설명이지만, Python의 동작 방식을 조금 더 깊게 이해하려면 다른 관점이 필요합니다. Java에서는 다음과 같이 primitive 값을 지역 변수에 직접 저장할 수 있습니다.int a = 10; 반면 Python에는 Java의 int, boolean, double과 같은 의미의 primitive type이 존재하지 않습니다. 10 역시 하나의 객체이며 a는 해당 객체와 연결된 이름입니다. 따라서 Python의 변수와 메모리 동작을 이해하기 위해서는 먼저 Object, Name, Binding, Namespace, Sco..
GIL Python의 멀티스레딩을 공부하다 보면 높은 확률로 GIL(Global Interpreter Lock)이라는 용어를 만나게 됩니다. 보통은 다음과 같이 설명합니다.CPython에서는 GIL 때문에 여러 스레드가 동시에 Python 코드를 실행할 수 없다. 설명 자체는 틀리지 않습니다. Python 공식 Glossary에서도 GIL을 한 번에 하나의 스레드만 Python bytecode를 실행하도록 보장하는 메커니즘이라고 설명합니다. 하지만 여기에서 자연스럽게 의문이 생겼습니다. Java에서는 하나의 프로세스 안에서 여러 스레드가 여러 CPU Core를 사용하여 코드를 병렬로 실행합니다. 공유 데이터에 대한 동기화 문제는 synchronized, Lock, Atomic 계열 등을 이용해 개발자가..
함수 정의와 호출 이번 글에서는 모든 프로그램에서 핵심이라 할 수 있는 함수 선언과 호출을 코틀린이 어떻게 개선했는지 살펴보겠습니다. 추가로 확장 함수와 프로퍼티를 사용해 혼합 언어 프로젝트에서 코틀린의 이점을 모두 살릴 수 있는 방법도 알아보겠습니다. 컬렉션 fun main() { val set = setOf(1, 7, 53) val list = listOf(1, 7, 53) val map = mapOf(1 to "one", 7 to "seven", 53 to "fifty-three") println(set.javaClass) // class java.util.LinkedHashSet println(list.javaClass) // class java.util.Array..
코틀린 기초 함수와 변수 이번 글에서는 모든 프로그램을 구성하는 기본 단위인 함수와 변수를 살펴보겠습니다.첫 번째 코틀린 코드를 작성하고 코틀린에서 타입 선언을 생략해도 된다는 사실을 보고, 코틀린이 어떻게 변경 가능한 데이터보다 변경할 수 없는 불변 데이터 사용을 권장하는지와 왜 불변 데이터가 더 좋은 것인지 살펴보겠습니다. Hello World 가장 기본적인 예제인 'Hello, World'를 출력하는 프로그램으로 시작해보겠습니다. 코틀린에서는 함수 하나로 이 프로그램을 만들 수 있습니다.함수를 선언할 때 fun 키워드를 사용합니다.함수를 모든 코틀린 파일의 최상위 수준에 정의할 수 있으므로 클래스 안에 넣어야 할 필요가 없습니다.최상위에 있는 main 함수를 애플리케이션의 진입점으로 지정할 수 있습..
코틀린이란? 코틀린(Kotlin)은 자바 가상머신(JVM) 플랫폼과 JVM 외의 다른 플랫폼에서 돌아가는 현대 프로그래밍 언어로, 처음에는 '더 나은 자바'로 시작했습니다. 즉, 개발자들이 일반적으로 저지를 수 있는 유형의 오류를 방지하고, 현대적 언어 설계 패러다임을 포용하면서도 자바가 쓰이던 모든 곳에 더 편리하게 쓸 수 있는 언어로 시작했습니다. 최근 10년간 코틀린은 자신이 여러 유형이 개발자, 프로젝트, 플랫폼에 실용적으로 잘 들어맞는 언어임을 증명해왔습니다. 안드로이드는 이제 코틀린 우선 플랫폼입니다. 이는 대부분의 안드로이드 개발자가 코틀린으로 개발을 한다는 뜻입니다. 스프링(spring) 같은 널리 쓰이는 프레임워크들이 코틀린을 네이티브로 지원하고 풍부한 코틀린 문서도 함께 제공하는 반면,..
Transport 이전에 [Java] Multiplexor 라는 글에서 Java NIO가 제공하는 Selector 기반의 이벤트 처리 모델을 살펴보았습니다. Selector는 단일 스레드가 수많은 소켓 이벤트를 동시에 감시할 수 있게 함으로써, 대규모 네트워크 연결을 효율적으로 관리하기 위해 등장한 메커니즘입니다. [Java] MultiplexerI/O Multiplexing 이란? I/O Multiplexing이라는 기술은 여러 개의 입출력 작업을 동시에 처리하는 기법을 의미합니다. 일반적으로 하나의 프로세스(혹은 싱글 스레드)가 여러 개의 I/O 요청을 처리해야 할freshdev.tistory.com Java NIO의 Selector는 플랫폼 독립적인 API를 제공하지만 실제 하부 동작은 운영체제의 ..