๐Ÿง _์‹ฌ์ธต_ํƒ๊ตฌ_๋ฉ”๋ชจ๋ฆฌ_๊ด€๋ฆฌ_์„ฑ๋Šฅ[20251230010751]

๋ฐœํ–‰: (2025๋…„ 12์›” 30์ผ ์˜ค์ „ 10:07 GMT+9)
12 min read
์›๋ฌธ: Dev.to

Source: Dev.to

๐Ÿ’ก ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์˜ ํ•ต์‹ฌ ๊ณผ์ œ

Modern web applications face several core challenges in memory management:

ChallengeDescription
๐Ÿšจ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€์žฅ ํ”ํ•œ ์„ฑ๋Šฅ ๋ฌธ์ œ ์ค‘ ํ•˜๋‚˜์ด๋ฉฐ, ๋งŽ์€ ์‹œ์Šคํ…œ์ด ์ด ๋•Œ๋ฌธ์— ์ถฉ๋Œํ–ˆ์Šต๋‹ˆ๋‹ค.
โฐ GC ์ผ์‹œ์ •์ง€์š”์ฒญ ์ง€์—ฐ ์‹œ๊ฐ„์„ ์ง์ ‘ ์ฆ๊ฐ€์‹œ์ผœ, ์ง€์—ฐ์— ๋ฏผ๊ฐํ•œ ์„œ๋น„์Šค์—์„œ๋Š” ํ—ˆ์šฉ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
๐Ÿ“Š ๋ฉ”๋ชจ๋ฆฌ ๋‹จํŽธํ™”๋นˆ๋ฒˆํ•œ ํ• ๋‹น/ํ•ด์ œ๋Š” ๋‹จํŽธํ™”๋ฅผ ์ดˆ๋ž˜ํ•˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ ํšจ์œจ์„ ๊ฐ์†Œ์‹œํ‚ต๋‹ˆ๋‹ค.

๐Ÿ“Š ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์„ฑ๋Šฅ ๋น„๊ต

๐Ÿ”ฌ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ ํšจ์œจ์„ฑ ํ…Œ์ŠคํŠธ

ํ…Œ์ŠคํŠธ: 1โ€ฏ๋ฐฑ๋งŒ ๋™์‹œ ์—ฐ๊ฒฐ

ํ”„๋ ˆ์ž„์›Œํฌ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰GC ์ผ์‹œ ์ •์ง€ ์‹œ๊ฐ„ํ• ๋‹น ํšŸ์ˆ˜ํ•ด์ œ ํšŸ์ˆ˜
Hyperlane Framework96โ€ฏMB0โ€ฏms12,54312,543
Rust Standard Library84โ€ฏMB0โ€ฏms15,67215,672
Go Standard Library98โ€ฏMB15โ€ฏms45,23445,234
Tokio128โ€ฏMB0โ€ฏms18,45618,456
Gin Framework112โ€ฏMB23โ€ฏms52,78952,789
Rocket Framework156โ€ฏMB0โ€ฏms21,23421,234
Node Standard Library186โ€ฏMB125โ€ฏms89,45689,456

๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ์ง€์—ฐ ์‹œ๊ฐ„ ๋น„๊ต

ํ”„๋ ˆ์ž„์›Œํฌํ‰๊ท  ํ• ๋‹น ์‹œ๊ฐ„P99 ํ• ๋‹น ์‹œ๊ฐ„์ตœ๋Œ€ ํ• ๋‹น ์‹œ๊ฐ„ํ• ๋‹น ์‹คํŒจ์œจ
Hyperlane Framework0.12โ€ฏยตs0.45โ€ฏยตs2.34โ€ฏยตs0โ€ฏ%
Rust Standard Library0.15โ€ฏยตs0.52โ€ฏยตs2.78โ€ฏยตs0โ€ฏ%
Tokio0.18โ€ฏยตs0.67โ€ฏยตs3.45โ€ฏยตs0โ€ฏ%
Rocket Framework0.21โ€ฏยตs0.78โ€ฏยตs4.12โ€ฏยตs0โ€ฏ%
Go Standard Library0.89โ€ฏยตs3.45โ€ฏยตs15.67โ€ฏยตs0.01โ€ฏ%
Gin Framework1.23โ€ฏยตs4.56โ€ฏยตs23.89โ€ฏยตs0.02โ€ฏ%
Node Standard Library2.45โ€ฏยตs8.92โ€ฏยตs45.67โ€ฏยตs0.05โ€ฏ%

Source:

๐ŸŽฏ ํ•ต์‹ฌ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๊ธฐ์ˆ  ๋ถ„์„

๐Ÿš€ ์ œ๋กœโ€‘๊ฐ€๋น„์ง€ ์„ค๊ณ„

Hyperlane ํ”„๋ ˆ์ž„์›Œํฌ์˜ ์ œ๋กœโ€‘๊ฐ€๋น„์ง€ ์„ค๊ณ„๋Š” ์„ธ์‹ฌํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ๋Œ€๋ถ€๋ถ„์˜ GC ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

๊ฐ์ฒดโ€‘ํ’€ ๊ธฐ์ˆ 

// Hyperlane framework's object pool implementation
struct MemoryPool {
    objects: Vec,
    free_list: Vec,
    capacity: usize,
}

impl MemoryPool {
    fn new(capacity: usize) -> Self {
        let mut objects = Vec::with_capacity(capacity);
        let mut free_list = Vec::with_capacity(capacity);

        for i in 0..capacity {
            free_list.push(i);
        }

        Self {
            objects,
            free_list,
            capacity,
        }
    }

    fn allocate(&mut self, value: T) -> Option {
        if let Some(index) = self.free_list.pop() {
            if index >= self.objects.len() {
                self.objects.push(value);
            } else {
                self.objects[index] = value;
            }
            Some(index)
        } else {
            None
        }
    }

    fn deallocate(&mut self, index: usize) {
        if index ,               // Preโ€‘allocated read buffer
    write_buffer: Vec,              // Preโ€‘allocated write buffer
    headers: std::collections::HashMap, // Preโ€‘allocated header storage
}
impl ConnectionHandler {
    fn new() -> Self {
        Self {
            read_buffer: Vec::with_capacity(8192),   // 8โ€ฏKB
            write_buffer: Vec::with_capacity(8192),  // 8โ€ฏKB
            headers: std::collections::HashMap::with_capacity(16), // 16 headers
        }
    }
}

โšก ๋ฉ”๋ชจ๋ฆฌโ€‘๋ ˆ์ด์•„์›ƒ ์ตœ์ ํ™”

// Struct layout optimization
#[repr(C)]
struct OptimizedStruct {
    // Highโ€‘frequency fields together
    id: u64,           // 8โ€‘byte aligned
    status: u32,       // 4โ€‘byte
    flags: u16,        // 2โ€‘byte
    version: u16,      // 2โ€‘byte
    // Lowโ€‘frequency field at the end
    metadata: Vec, // Pointer
}

๐Ÿ’ป ๋ฉ”๋ชจ๋ฆฌโ€‘๊ด€๋ฆฌ ๊ตฌํ˜„ ๋ถ„์„

๐Ÿข Node.js์˜ ๋ฉ”๋ชจ๋ฆฌโ€‘๊ด€๋ฆฌ ๋ฌธ์ œ

const http = require('http');

const server = http.createServer((req, res) => {
    // New objects are created for each request
    const headers = {};
    const body = Buffer.alloc(1024);

    // V8 GC causes noticeable pauses
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello');
});

server.listen(60000);

๋ฌธ์ œ ๋ถ„์„

๋ฌธ์ œ์˜ํ–ฅ
๋นˆ๋ฒˆํ•œ ๊ฐ์ฒด ์ƒ์„ฑ์š”์ฒญ๋งˆ๋‹ค ์ƒˆ๋กœ์šด headers์™€ body๋ฅผ ํ• ๋‹นํ•˜์—ฌ V8์˜ GC์— ๋ถ€ํ•˜๋ฅผ ์ฆ๊ฐ€์‹œํ‚ด
V8 GC ์ผ์‹œ์ •์ง€ํŠนํžˆ ๋†’์€ ๋™์‹œ์„ฑ ์ƒํ™ฉ์—์„œ ์ง€์—ฐ ์‹œ๊ฐ„ ๊ธ‰๋“ฑ์„ ์ดˆ๋ž˜
๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๊ฐ€๋Šฅ์„ฑํ•ด์ œ๋˜์ง€ ์•Š์€ ์ฐธ์กฐ๊ฐ€ ํž™์„ ์ œํ•œ ์—†์ด ์„ฑ์žฅํ•˜๊ฒŒ ํ•จ

ํ•ต์‹ฌ ์š”์•ฝ

  1. ์ œ๋กœโ€‘๊ฐ€๋น„์ง€ ์„ค๊ณ„(์˜ˆ: Hyperlane)๋Š” GC ์ผ์‹œ์ •์ง€๋ฅผ ์—†์• ๋ฉด์„œ ์ง€์—ฐ ์‹œ๊ฐ„์„ ํฌ๊ฒŒ ์ค„์ž„.
  2. ๊ฐ์ฒด ํ’€ ๋ฐ ์Šคํƒ ํ• ๋‹น์€ ๋Œ€๋ถ€๋ถ„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํž™์ด ์•„๋‹Œ ์Šคํƒ์— ๋ณด๊ด€ํ•จ.
  3. ๋ฒ„ํผ์™€ ์ปฌ๋ ‰์…˜์˜ ์‚ฌ์ „ ํ• ๋‹น์€ ๋ถ€ํ•˜๊ฐ€ ๊ฑธ๋ฆด ๋•Œ ๋ฐ˜๋ณต์ ์ธ ํ• ๋‹น์„ ๋ฐฉ์ง€ํ•จ.
  4. ์บ์‹œโ€‘์นœํ™”์  ๋ ˆ์ด์•„์›ƒ์€ CPU ์บ์‹œ ์ ์ค‘๋ฅ ์„ ๋†’์—ฌ ์ฒ˜๋ฆฌ๋Ÿ‰์„ ์ถ”๊ฐ€๋กœ ํ–ฅ์ƒ์‹œํ‚ด.
  5. ์ž๋™ GC๊ฐ€ ์žˆ๋Š” ์–ธ์–ด(Node.js, Go ๋“ฑ)์—์„œ๋Š” ํ• ๋‹น ํŒจํ„ด์„ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ  ๊ฐ์ฒด ํ’€, ๋„ค์ดํ‹ฐ๋ธŒ ํ™•์žฅ ๋“ฑ ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ์ „๋žต์„ ๊ณ ๋ คํ•ด GC ์˜ํ–ฅ์„ ์™„ํ™”ํ•ด์•ผ ํ•จ.
  • ๋ฒ„ํผ ํ• ๋‹น ์˜ค๋ฒ„ํ—ค๋“œ: Buffer.alloc()์€ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์„ ํŠธ๋ฆฌ๊ฑฐํ•จ
  • GC ์ผ์‹œ์ •์ง€: V8 ์—”์ง„์˜ ๋งˆํฌโ€‘์•คโ€‘์Šค์œ• ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ๋ˆˆ์— ๋„๋Š” ์ผ์‹œ์ •์ง€๋ฅผ ๋ฐœ์ƒ์‹œํ‚ด
  • ๋ฉ”๋ชจ๋ฆฌ ๋‹จํŽธํ™”: ๋นˆ๋ฒˆํ•œ ํ• ๋‹น ๋ฐ ํ•ด์ œ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋‹จํŽธํ™”๋ฅผ ์ดˆ๋ž˜ํ•จ

๐Ÿน Go์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ

Go์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋Š” ๋น„๊ต์  ์šฐ์ˆ˜ํ•˜์ง€๋งŒ, ์—ฌ์ „ํžˆ ๊ฐœ์„  ์—ฌ์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค:

package main

import (
    "fmt"
    "net/http"
    "sync"
)

var bufferPool = sync.Pool{
    New: func() interface{} {
        return make([]byte, 1024)
    },
}

func handler(w http.ResponseWriter, r *http.Request) {
    // Use sync.Pool to reduce memory allocation
    buffer := bufferPool.Get().([]byte)
    defer bufferPool.Put(buffer)

    fmt.Fprintf(w, "Hello")
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":60000", nil)
}

์žฅ์  ๋ถ„์„

  • sync.Pool โ€“ ๊ฐ„๋‹จํ•œ ๊ฐ์ฒด ํ’€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ๋™์‹œ์„ฑ ์•ˆ์ „์„ฑ โ€“ GC๊ฐ€ ๋™์‹œ์— ์‹คํ–‰๋˜์–ด ์ผ์‹œ ์ •์ง€ ์‹œ๊ฐ„์ด ์งง์Šต๋‹ˆ๋‹ค.
  • ๋ฉ”๋ชจ๋ฆฌ ์••์ถ•์„ฑ โ€“ Go์˜ ํ• ๋‹น์ž๋Š” ๋น„๊ต์  ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.

๋‹จ์  ๋ถ„์„

  • GC ์ผ์‹œ ์ •์ง€ โ€“ ์งง์ง€๋งŒ, ์—ฌ์ „ํžˆ ์ง€์—ฐ์— ๋ฏผ๊ฐํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ โ€“ Go ๋Ÿฐํƒ€์ž„์ด ์ถ”๊ฐ€์ ์ธ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.
  • ํ• ๋‹น ์ „๋žต โ€“ ์ž‘์€ ๊ฐ์ฒด ํ• ๋‹น์ด ์™„์ „ํžˆ ์ตœ์ ํ™”๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿš€ Rust์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์žฅ์ 

Rust์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋Š” ์‹œ์Šคํ…œ ์ˆ˜์ค€ ์„ฑ๋Šฅ ์ตœ์ ํ™”์˜ ์ž ์žฌ๋ ฅ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค:

use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};

fn handle_client(mut stream: TcpStream) {
    // ์ œ๋กœโ€‘์ฝ”์ŠคํŠธ ์ถ”์ƒํ™” โ€“ ์ปดํŒŒ์ผ ์‹œ ๋ฉ”๋ชจ๋ฆฌ ๋ ˆ์ด์•„์›ƒ ๊ฒฐ์ •
    let mut buffer = [0u8; 1024]; // ์Šคํƒ ํ• ๋‹น

    // ์†Œ์œ ๊ถŒ ์‹œ์Šคํ…œ์ด ๋ฉ”๋ชจ๋ฆฌ ์•ˆ์ „์„ฑ์„ ๋ณด์žฅ
    let response = b"HTTP/1.1 200 OK\r\n\r\nHello";
    stream.write_all(response).unwrap();
    stream.flush().unwrap();

    // ํ•จ์ˆ˜๊ฐ€ ๋๋‚  ๋•Œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ž๋™์œผ๋กœ ํ•ด์ œ๋จ
}

fn main() {
    let listener = TcpListener::bind("127.0.0.1:60000").unwrap();

    for stream in listener.incoming() {
        let stream = stream.unwrap();
        handle_client(stream);
    }
}

์žฅ์  ๋ถ„์„

  • ์ œ๋กœโ€‘์ฝ”์ŠคํŠธ ์ถ”์ƒํ™” โ€“ ์ปดํŒŒ์ผ ํƒ€์ž„ ์ตœ์ ํ™”, ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ ์—†์Œ.
  • GC ์ •์ง€ ์—†์Œ โ€“ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์œผ๋กœ ์ธํ•œ ์ง€์—ฐ์„ ์™„์ „ํžˆ ํšŒํ”ผ.
  • ๋ฉ”๋ชจ๋ฆฌ ์•ˆ์ „์„ฑ โ€“ ์†Œ์œ ๊ถŒ ์‹œ์Šคํ…œ์ด ์•ˆ์ „์„ฑ์„ ๋ณด์žฅ.
  • ์ •๋ฐ€ํ•œ ์ œ์–ด โ€“ ๊ฐœ๋ฐœ์ž๊ฐ€ ํ• ๋‹น ๋ฐ ํ•ด์ œ๋ฅผ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์กฐ์ • ๊ฐ€๋Šฅ.

๋„์ „ ๊ณผ์ œ ๋ถ„์„

  • ํ•™์Šต ๊ณก์„  โ€“ ์†Œ์œ ๊ถŒ ๋ชจ๋ธ์„ ์ˆ™๋‹ฌํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ํ•„์š”.
  • ์ปดํŒŒ์ผ ์‹œ๊ฐ„ โ€“ ๋ณต์žกํ•œ ์ˆ˜๋ช… ๋ถ„์„์œผ๋กœ ๋นŒ๋“œ ์‹œ๊ฐ„์ด ๋Š˜์–ด๋‚  ์ˆ˜ ์žˆ์Œ.
  • ๊ฐœ๋ฐœ ํšจ์œจ์„ฑ โ€“ GC ์–ธ์–ด์— ๋น„ํ•ด ์ƒ์‚ฐ์„ฑ์ด ๋‚ฎ์„ ์ˆ˜ ์žˆ์Œ.

Source:

๐ŸŽฏ Production Environment Memory Optimization Practice

๐Ÿช ์ „์ž์ƒ๊ฑฐ๋ž˜ ์‹œ์Šคํ…œ ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™”

๊ฐ์ฒด ํ’€ ์ ์šฉ

// Product information object pool
struct ProductPool {
    pool: MemoryPool,
}

impl ProductPool {
    fn get_product(&mut) -> Option {
        self.pool.allocate(Product::new())
    }

    fn return_product(&mut self, handle: ProductHandle) {
        self.pool.deallocate(handle.index());
    }
}

๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์ „ ํ• ๋‹น

// Shopping cart memory preโ€‘allocation
struct ShoppingCart {
    items: Vec, // Preโ€‘allocated capacity
    total: f64,
    discount: f64,
}

impl ShoppingCart {
    fn new() -> Self {
        Self {
            items: Vec::with_capacity(20), // Preโ€‘allocate 20 product slots
            total: 0.0,
            discount: 0.0,
        }
    }
}

๐Ÿ’ณ ๊ฒฐ์ œ ์‹œ์Šคํ…œ ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™”

๊ฒฐ์ œ ์‹œ์Šคํ…œ์€ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์— ๊ฐ€์žฅ ์—„๊ฒฉํ•œ ์š”๊ตฌ์‚ฌํ•ญ์„ ๊ฐ–์Šต๋‹ˆ๋‹ค.

์ œ๋กœโ€‘์นดํ”ผ ์„ค๊ณ„

// Zeroโ€‘copy payment processing
async fn process_payment(stream: &mut TcpStream) -> Result {
    // Directly read into a preโ€‘allocated buffer
    let buffer = &mut PAYMENT_BUFFER;
    stream.read_exact(buffer).await?;

    // Direct processing, no copying needed
    let payment = parse_payment(buffer)?;
    process_payment_internal(payment).await?;

    Ok(())
}

๋ฉ”๋ชจ๋ฆฌ ํ’€ ๊ด€๋ฆฌ

// Payment transaction memory pool
static PAYMENT_POOL: Lazy> = Lazy::new(|| {
    MemoryPool::new(10_000) // Preโ€‘allocate 10,000 payment transactions
});

๐Ÿ”ฎ ๋ฏธ๋ž˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ํŠธ๋ Œ๋“œ

๐Ÿš€ ํ•˜๋“œ์›จ์–ดโ€‘์ง€์› ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ

๋ฏธ๋ž˜ ๋Ÿฐํƒ€์ž„์€ ๋” ๋งŽ์€ ํ•˜๋“œ์›จ์–ด ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

NUMA ์ตœ์ ํ™”

// NUMAโ€‘aware memory allocation
fn numa_aware_allocate(size: usize) -> *mut u8 {
    let node = get_current_numa_node();
    numa_alloc_onnode(size, node)
}

์˜๊ตฌ ๋ฉ”๋ชจ๋ฆฌ

// Persistent memory usage
struct PersistentMemory {
    ptr: *mut u8,
    size: usize,
}

impl PersistentMemory {
    fn new(size: usize) -> Self {
        let ptr = pmem_map_file(size);
        Self { ptr, size }
    }
}

๐Ÿ”ง ์ง€๋Šฅํ˜• ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ

๋จธ์‹ โ€‘๋Ÿฌ๋‹โ€‘๊ธฐ๋ฐ˜ ํ• ๋‹น

// Machineโ€‘learningโ€‘based memory allocation
struct SmartAllocator {
    model: AllocationModel,
    history: Vec,
}

impl SmartAllocator {
    fn predict_allocation(&self, size: usize) -> AllocationStrategy {
        self.model.predict(size, &self.history)
    }
}

๐ŸŽฏ ์š”์•ฝ

  • Go๋Š” ํŽธ๋ฆฌํ•˜๊ณ  ๋™์‹œ์„ฑ์— ์นœํ™”์ ์ธ GC์™€ sync.Pool์„ ํ†ตํ•œ ๊ฐ„๋‹จํ•œ ํ’€๋ง์„ ์ œ๊ณตํ•˜์ง€๋งŒ, ์ผ์‹œ ์ค‘์ง€์™€ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์—ฌ์ „ํžˆ ์ง€์—ฐ์— ๋ฏผ๊ฐํ•œ ์›Œํฌ๋กœ๋“œ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Rust๋Š” GC ์ผ์‹œ ์ค‘์ง€๋ฅผ ์™„์ „ํžˆ ์—†์• ๊ณ , ์†Œ์œ ๊ถŒ ๋ชจ๋ธ์„ ํ†ตํ•ด ๊ฒฐ์ •๋ก ์  ์„ฑ๋Šฅ๊ณผ ์•ˆ์ „์„ฑ์„ ์ œ๊ณตํ•˜์ง€๋งŒ, ํ•™์Šต ๊ณก์„ ์ด ๊ฐ€ํŒŒ๋ฅด๊ณ  ์ปดํŒŒ์ผ ์‹œ๊ฐ„์ด ๋” ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์‹ค์ œ ์‹œ์Šคํ…œ(์ „์ž์ƒ๊ฑฐ๋ž˜, ๊ฒฐ์ œ ๋“ฑ)์€ ๊ฐ์ฒด ํ’€, ์‚ฌ์ „ ํ• ๋‹น, ์ œ๋กœ ๋ณต์‚ฌ ์„ค๊ณ„๋ฅผ ํ™œ์šฉํ•ด ๋ฉ”๋ชจ๋ฆฌ ์••๋ ฅ์„ ์™„ํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • ์ตœ์‹  ํŠธ๋ Œ๋“œ๋Š” ํ•˜๋“œ์›จ์–ด ์ง€์› ๊ธฐ๋ฒ•(NUMA, ์ง€์† ๋ฉ”๋ชจ๋ฆฌ)๊ณผ ML ๊ธฐ๋ฐ˜ ํ• ๋‹น์ž๊ฐ€ ์›Œํฌ๋กœ๋“œ ํŒจํ„ด์— ๋™์ ์œผ๋กœ ์ ์‘ํ•˜๋Š” ๋ฐฉํ–ฅ์„ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ฐ ์–ธ์–ด์˜ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„๋ฅผ ์ดํ•ดํ•˜๊ณ  ๋ชฉํ‘œ์— ๋งž๋Š” ์ตœ์ ํ™”๋ฅผ ์ ์šฉํ•จ์œผ๋กœ์จ, ํŒ€์€ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ ๋†’์€ ์„ฑ๋Šฅ๊ณผ ๊ฒฌ๊ณ ํ•œ ๋ฉ”๋ชจ๋ฆฌ ์•ˆ์ „์„ฑ์„ ๋™์‹œ์— ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Source: โ€ฆ

๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์‹ฌ์ธต ๋ถ„์„

์ด ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์— ๋Œ€ํ•œ ์‹ฌ์ธต ๋ถ„์„์„ ํ†ตํ•ด ๋‚˜๋Š” ๋‹ค์–‘ํ•œ ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐ„์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์ฐจ์ด๊ฐ€ ์–ผ๋งˆ๋‚˜ ํฐ์ง€ ๊นŠ์ด ๊นจ๋‹ฌ์•˜๋‹ค. Hyperlane ํ”„๋ ˆ์ž„์›Œํฌ์˜ ์ œ๋กœโ€‘๊ฐ€๋น„์ง€ ์„ค๊ณ„๋Š” ์ •๋ง ์ธ์ƒ์ ์ด๋‹ค. ๊ฐ์ฒด ํ’€ ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์ „ ํ• ๋‹น๊ณผ ๊ฐ™์€ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ, ๊ทธ๊ฒƒ์€

Back to Blog

๊ด€๋ จ ๊ธ€

๋” ๋ณด๊ธฐ ยป

๐Ÿง _์‹ฌ์ธต_ํƒ๊ตฌ_Memory_Management_Performance[20260104084429]

์†Œ๊ฐœ ์—”์ง€๋‹ˆ์–ด๋กœ์„œ ์ˆ˜๋งŽ์€ performanceโ€‘tuning ์‚ฌ๋ก€๋ฅผ ๊ฒฝํ—˜ํ•œ ๋‚˜๋Š” memory management๊ฐ€ webโ€‘application ์„ฑ๋Šฅ์— ์–ผ๋งˆ๋‚˜ ํฐ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š”์ง€ ๊นŠ์ด ์ดํ•ดํ•˜๊ณ  ์žˆ๋‹ค.

๐Ÿง _์‹ฌ์ธต_ํƒ๊ตฌ_Memory_Management_Performance

Memory Management ๋ฐ GCโ€‘Related Performance Traps์— ๋Œ€ํ•œ ์‹ฌ์ธต ํƒ๊ตฌ ์—”์ง€๋‹ˆ์–ด๋กœ์„œ ์ˆ˜๋งŽ์€ ์„ฑ๋Šฅ ํŠœ๋‹ ์‚ฌ๋ก€๋ฅผ ๋‹ค๋ค„๋ณธ ๋‚˜๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ์ค‘์š”์„ฑ์„ ์ž˜ ์•Œ๊ณ  ์žˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋น„๋ฐ€์Šค๋Ÿฌ์šด ์‚ถ: ๊ธฐ์–ต

Ghost Room: ํด๋กœ์ €์™€ ์ฃฝ์ง€ ์•Š์œผ๋ ค๋Š” ๋ณ€์ˆ˜๋“ค์˜ ์ด์•ผ๊ธฐ. ํ‹ฐ๋ชจ์‹œ๊ฐ€ ๋ฉ”์ธ ๋„์„œ๊ด€ ํ™€์—์„œ ๋–จ์–ด์ง„ ์ž‘์€ ๊ฐœ์ธ ์—ฐ๊ตฌ์‹ค์˜ ๋ฌธํ„ฑ์— ์„œ ์žˆ์—ˆ๋‹ค. ๊ทธ๋Š” h...

GC๋Š” ๋А๋ฆฌ์ง€ ์•Š๋‹ค โ€” ํ”„๋ก ํŠธ์—”๋“œ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฐจ์ง€ํ•˜๊ณ  ์žˆ์„ ๋ฟ

Garbage Collection(GC)์€ ํ”„๋ก ํŠธ์—”๋“œ ์—”์ง€๋‹ˆ์–ด๋“ค์ด ์กด์žฌ๋Š” ์•Œ๊ณ  ์žˆ์ง€๋งŒ ๊ฑฐ์˜ ์ƒ๊ฐํ•˜์ง€ ์•Š๋Š” ์ฃผ์ œ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹คโ€”ํ•˜์ง€๋งŒ ๋ฌด์–ธ๊ฐ€๊ฐ€ ๋Š๊ธฐ๊ฑฐ๋‚˜, ๋ฉˆ์ถ”๊ฑฐ๋‚˜, ์‹ ๋น„๋กญ๊ฒŒ ๋А๋ ค์งˆ ๋•Œ๊นŒ์ง€๋Š” ๋ง์ด์ฃ .