Coding Planet

[์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”]chapter2 : [์•„์ดํ…œ7] ๋‹ค ์“ด ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ํ•ด์ œํ•˜๋ผ ๋ณธ๋ฌธ

๐Ÿ’ป Java Study/Java ์ด๋ก  ์ •๋ฆฌ

[์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”]chapter2 : [์•„์ดํ…œ7] ๋‹ค ์“ด ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ํ•ด์ œํ•˜๋ผ

jhj.sharon 2023. 8. 19. 20:40
๋ฐ˜์‘ํ˜•

์•„์ดํ…œ7 :  ๋‹ค ์“ด ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ํ•ด์ œํ•˜๋ผ

 

C, C++ ์–ธ์–ด๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ง์ ‘ ๊ด€๋ฆฌํ•˜์ง€๋งŒ ์ž๋ฐ”์˜ ๊ฒฝ์šฐ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ์ด ์—ญํ• ์„ ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค ์“ด ๊ฐ์ฒด๋Š” ์•Œ์•„์„œ ํšŒ์ˆ˜๋œ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๊ฒƒ์ด ๋ฉ”๋กœ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š์•„๋„๋œ๋‹ค๋Š” ์˜๋ฏธ๋Š” ์•„๋‹ˆ๋‹ค. 

 

1. ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์ผ์–ด๋‚˜๋Š” ์œ„์น˜๋Š” ์–ด๋””์ธ๊ฐ€?

public class Stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;

    public Stack() {
        elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }

    public void push(Object e) {
        ensureCapacity();
        elements[size++] = e;
    }

    public Object pop() {
        if (size == 0) {
            throw new EmptyStackException();
        }
        return elements[--size];
    }

    private void ensureCapacity() {
        if (elements.length == size) {
            elements = Arrays.copyOf(elements, 2 * size + 1);
        }
    }
}
  • ์œ„ ์ฝ”๋“œ์—์„œ๋Š” ์Šคํƒ์ด ์ปค์กŒ๋‹ค๊ฐ€ ์ค„์–ด๋“ค์—ˆ์„ ๋•Œ ์Šคํƒ์—์„œ ๊บผ๋‚ด์ง„ ๊ฐ์ฒด๋“ค์„ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ํšŒ์ˆ˜ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ์Šคํƒ์ด ๊ทธ ๊ฐ์ฒด๋“ค์˜ ๋‹ค ์“ด ์ฐธ์กฐ(obsolete reference)๋ฅผ ์—ฌ์ „ํžˆ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋‹ค ์“ด ์ฐธ์กฐ๋ž€ ๋ฌธ์ž ๊ทธ๋Œ€๋กœ ์•ž์œผ๋กœ ๋‹ค์‹œ ์“ฐ์ง€ ์•Š์„ ์ฐธ์กฐ๋ฅผ ๋œปํ•œ๋‹ค.
  •  ์ฝ”๋“œ์—์„œ๋Š” elements ๋ฐฐ์—ด์˜ 'ํ™œ์„ฑ ์˜์—ญ'๋ฐ–์˜ ์ฐธ์กฐ๋“ค์ด ๋ชจ๋‘ ์—ฌ๊ธฐ์— ํ•ด๋‹นํ•œ๋‹ค. ํ™œ์„ฑ ์˜์—ญ์€ ์ธ๋ฑ์Šค๊ฐ€ size๋ณด๋‹ค ์ž‘์€ ์›์†Œ๋“ค๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.
  • ๊ฐ์ฒด ํ•˜์ฐธ์กฐ ํ•˜๋‚˜๋ฅผ ์‚ด๋ ค๋‘๋ฉด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ๊ทธ ๊ฐ์ฒด ๋ฟ ์•„๋‹ˆ๋ผ ๊ทธ ๊ฐ์ฒด๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ํšŒ์ˆ˜ํ•˜์ง€ ๋ชปํ•œ๋‹ค. ์ด๋กœ ์ธํ•ด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์ผ์–ด๋‚˜๊ฒŒ ๋œ๋‹ค.
ํ™œ์„ฑ์˜์—ญ(Active Region)
- ํ™œ์„ฑ์˜์—ญ์€ 'elememts' ๋ฐฐ์—ด์—์„œ ํ˜„์žฌ ์‚ฌ์šฉ ์ค‘์ธ, ์ฆ‰ ์Šคํƒ์— ์‹ค์ œ๋กœ ์ €์žฅ๋œ ์š”์†Œ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.
- ์Šคํƒ์—์„œ 'size'๋ณ€์ˆ˜๋Š” ์Šคํƒ์˜ ํ˜„์žฌ ํฌ๊ธฐ, ์ฆ‰ ์ €์žฅ๋œ ์š”์†Œ์˜ ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๋”ฐ๋ผ์„œ 'elements'๋ฐฐ์—ด์—์„œ ์ธ๋ฑ์Šค๊ฐ€ 0๋ถ€ํ„ฐ 'size-1'๊นŒ์ง€์˜ ์›์†Œ๋“ค์ด ํ™œ์„ฑ ์˜์—ญ์ด๋‹ค.

๋‹ค ์“ด ์ฐธ์กฐ (Obsolete Reference)
- ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ๋” ์ด์ƒ ํ•„์š”ํ•˜์ง€ ์•Š์ง€๋งŒ, ์ฐธ์กฐ๊ฐ€ ์—ฌ์ „ํžˆ ์กด์žฌํ•˜๊ณ  ์žˆ์–ด ๊ฐ€๋น„์ง€ ์ปฌ๋Ÿญํ„ฐ๊ฐ€ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ํšŒ์ˆ˜ํ•˜์ง€ ๋ชปํ•˜๋Š” ์ƒํ™ฉ์„ ์˜๋ฏธํ•œ๋‹ค.
- 'pop' ๋ฉ”์„œ๋“œ์—์„œ ์š”์†Œ๋ฅผ ์Šคํƒ์—์„œ ์ œ๊ฑฐํ•  ๋•Œ, ์‹ค์ œ๋กœ๋Š” ํ•ด๋‹น ์š”์†Œ์˜ ์ฐธ์กฐ๋ฅผ 'elements' ๋ฐฐ์—ด์—์„œ ์ œ๊ฑฐํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋Œ€์‹  'size' ๋ณ€์ˆ˜๋งŒ ๊ฐ์†Œ์‹œ์ผœ 'ํ™œ์„ฑ ์˜์—ญ'์„ ์ค„์ธ๋‹ค. ์ด๋กœ์ธํ•ด 'size'๋ณด๋‹ค ํฐ ์ธ๋ฑ์Šค์— ์žˆ๋Š” ์š”์†Œ๋“ค์€ "๋‹ค ์“ด ์ฐธ์กฐ"๊ฐ€ ๋˜๋ฉฐ, ์ด ์ฐธ์กฐ๋“ค ๋•Œ๋ฌธ์— ํ•ด๋‹น ๊ฐ์ฒด๋“ค์ด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ์— ์˜ํ•ด ํšŒ์ˆ˜๋˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค.

 

 

2. ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

  • ํ•ด๋‹น ์ฐธ์กฐ๋ฅผ ๋‹ค ์ผ์„ ๋•Œ null ์ฒ˜๋ฆฌ(์ฐธ์กฐ ํ•ด์ œ)ํ•˜๋ฉด ๋œ๋‹ค. ์ œ๋Œ€๋กœ ๊ตฌํ˜„๋œ pop ๋ฉ”์„œ๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
public class Stack {

    // ...

    public Object pop() {
        if (size == 0) {
            throw new EmptyStackException();
        }
        Object result = elements[--size];
        elements[size] = null; // ๋‹ค ์“ด ์ฐธ์กฐ ํ•ด์ œ
        return result;
    }
}
  • ์œ„์ฒ˜๋Ÿผ ๋‹ค ์“ด ์ฐธ์กฐ๋ฅผ null๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉด null ์ฒ˜๋ฆฌํ•œ ์ฐธ์กฐ๋ฅผ ์‹ค์ˆ˜๋กœ ์‚ฌ์šฉํ•˜๋ ค ํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์€ ์ฆ‰์‹œ NullPointerException์„ ๋˜์ง€๋ฉฐ ์ข…๋ฃŒ๋˜๋ฏ€๋กœ ํ”„๋กœ๊ทธ๋žจ ์˜ค๋ฅ˜๋ฅผ ์กฐ๊ธฐ์— ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ null ์ฒ˜๋ฆฌํ•˜๋Š” ์ผ์€ ์˜ˆ์™ธ์ ์ธ ๊ฒฝ์šฐ์—ฌ์•ผ ํ•œ๋‹ค. ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ๋‹ค ์“ฐ์ž๋งˆ์ž ์ผ์ผ์ด null ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ํ”„๋กœ๊ทธ๋žจ์„ ํ•„์š” ์ด์ƒ์œผ๋กœ ์ง€์ €๋ถ„ํ•˜๊ฒŒ ๋งŒ๋“ค ๋ฟ์ด๋‹ค.
  • ๋‹ค ์“ด ์ฐธ์กฐ๋ฅผ ํ•ด์ œํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ๊ทธ ์ฐธ์กฐ๋ฅผ ๋‹ด์€ ๋ณ€์ˆ˜๋ฅผ ์œ ํšจ ๋ฒ”์œ„(scope) ๋ฐ–์œผ๋กœ ๋ฐ€์–ด๋‚ด๋Š” ๊ฒƒ์ด๋‹ค. ๋ณ€์ˆ˜์˜ ๋ฒ”์œ„๋ฅผ ์ตœ์†Œ๊ฐ€ ๋˜๊ฒŒ ์ •์˜ํ•˜์ž.
  • ์•„๋ž˜์ฒ˜๋Ÿผ ์ˆ˜์ •ํ•˜๋ฉด, result ๋ณ€์ˆ˜๋Š” pop ๋ฉ”์„œ๋“œ์˜ ์ง€์—ญ ๋ณ€์ˆ˜์ด๋ฏ€๋กœ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ ์ž๋™์œผ๋กœ ๋ฒ”์œ„(scope)๋ฅผ ๋ฒ—์–ด๋‚˜๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ result์— ์ €์žฅ๋œ ๊ฐ์ฒด ์ฐธ์กฐ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ์ž๋™์œผ๋กœ ํ•ด์ œ๋œ๋‹ค.
public Object pop() {
    if (size == 0) {
        throw new EmptyStackException();
    }
    
    // ์ง€์—ญ ๋ณ€์ˆ˜๋กœ ๊ฐ์ฒด ์ฐธ์กฐ ๊ฐ€์ ธ์˜ค๊ธฐ
    Object result = elements[size - 1];
    
    // ์ฐธ์กฐ๋ฅผ ํ•ด์ œ
    elements[size - 1] = null;
    size--;
    
    // ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜
    return result;
}

 

 

| ๊ทธ๋ ‡๋‹ค๋ฉด null ์ฒ˜๋ฆฌ๋Š” ์–ธ์ œ ํ•ด์•ผํ• ๊นŒ??

  • ์ผ๋ฐ˜์ ์œผ๋กœ ์ž๊ธฐ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ง์ ‘ ๊ด€๋ฆฌํ•˜๋Š” ํด๋ž˜์Šค๋ผ๋ฉด ํ•ญ์‹œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜์— ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค. ์›์†Œ๋ฅผ ๋‹ค ์‚ฌ์šฉํ•œ ์ฆ‰์‹œ ๊ทธ ์›์†Œ๊ฐ€ ์ฐธ์กฐํ•œ ๊ฐ์ฒด๋“ค์„ ๋‹ค null ์ฒ˜๋ฆฌํ•ด์ค˜์•ผ ํ•œ๋‹ค. stack ํด๋ž˜์Šค ๋˜ํ•œ ์ž๊ธฐ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ elements ๋ฐฐ์—ด๋กœ ์ €์žฅ์†Œ ํ’€์„ ๋งŒ๋“ค์–ด ์ง์ ‘ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ ๋ˆ„์ˆ˜์— ์ทจ์•ฝํ•  ์ˆ˜ ๋ฐ–์— ๋ฒ—๋‹ค.
  • ๊ทธ๋Ÿฌ๋ฏ€๋กœ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ๋น„ํ™œ์„ฑ ์˜์—ญ์ด ๋˜๋Š” ์ˆœ๊ฐ„ null์ฒ˜๋ฆฌํ•ด์„œ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ๋”๋Š” ์“ฐ์ง€ ์•Š์„ ๊ฒƒ์ž„์„ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ์— ์•Œ๋ ค์•ผํ•œ๋‹ค.

 

3. ์บ์‹œ์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

  • ์บ์‹œ ์—ญ์‹œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ์ผ์œผํ‚ค๋Š” ์ฃผ๋ฒ”์ด๋‹ค. ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ์บ์‹œ์— ๋„ฃ์–ด๋‘๊ณ  ์ด ์‚ฌ์‹ค์„ ๊นŒ๋งฃ๊ฒŒ ์žŠ์€ ์ฑ„ ๊ทธ ๊ฐ์ฒด๋ฅผ ๋‹ค์“ด ๋’ค๋กœ๋„ ํ•œ์ฐธ ๊ทธ๋ƒฅ ๋†”๋‘˜ ์ˆ˜ ๋„ ์žˆ๋‹ค.
  • ์บ์‹œ ์™ธ๋ถ€์—์„œ ํ‚ค(key)๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋™์•ˆ๋งŒ(๊ฐ’์ด ์•„๋‹ˆ๋‹ค) ์—”ํŠธ๋ฆฌ๊ฐ€ ์‚ด์•„ ์žˆ๋Š” ์บ์‹œ๊ฐ€ ํ•„์š”ํ•œ ์ƒํ™ฉ์ด๋ผ๋ฉด WeakHashMap์„ ์‚ฌ์šฉํ•ด ์บ์‹œ๋ฅผ ๋งŒ๋“ค์ž.
  • ๋‹ค ์“ด ์—”ํŠธ๋ฆฌ๋Š” ๊ทธ ์ฆ‰์‹œ ์ž๋™์œผ๋กœ ์ œ๊ฑฐ๋  ๊ฒƒ์ด๋‹ค. ๋‹จ, WeakHashMap์€ ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์—์„œ๋งŒ ์œ ์šฉํ•˜๋‹ค.
WeakHashMap์™€ ์•ฝํ•œ ์ฐธ์กฐ(weak reference)
- ๊ธฐ๋ณธ์ ์œผ๋กœ HashMap๊ณผ ์œ ์‚ฌํ•˜์ง€๋งŒ ํ‚ค์— ๋Œ€ํ•œ ์ฐธ์กฐ๊ฐ€ ์•ฝํ•œ์ฐธ์กฐ(weak reference)๋กœ ์ €์žฅ๋˜๋Š” ๊ฒƒ์ด ํŠน์ง•์ด๋‹ค.
- ์•ฝํ•œ ์ฐธ์กฐ๋ž€ WeakHashMap์˜ ํ‚ค๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด์— ๋Œ€ํ•œ ์œ ์ผํ•œ ์ฐธ์กฐ๊ฐ€  WeakHashMap ๋‚ด๋ถ€์—๋งŒ ์žˆ์–ด ์ผ๋ฐ˜์ ์ธ ์ฐธ์กฐ์™€ ๋‹ฌ๋ฆฌ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ์— ์˜ํ•ด ์–ธ์ œ๋“ ์ง€ ํšŒ์ˆ˜๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ํŠน์ง•์ด์žˆ๋‹ค. 

 

import java.util.WeakHashMap;

public class Example {
    public static void main(String[] args) {
        WeakHashMap<Object, String> weakMap = new WeakHashMap<>();

        Object key = new Object();
        weakMap.put(key, "value");

        System.out.println("Before nulling key: " + weakMap);

        key = null; // key์— ๋Œ€ํ•œ strong reference๋ฅผ ์ œ๊ฑฐ

        System.gc(); // ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ ํ˜ธ์ถœ

        System.out.println("After GC: " + weakMap); // map ์ œ๊ฑฐ
    }
}

 

 

4. ์บ์‹œ์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•

  • ์บ์‹œ๋ฅผ ๋งŒ๋“ค ๋•Œ ๋ณดํ†ต์€ ์บ์‹œ ์—”ํŠธ๋ฆฌ์˜ ์œ ํšจ ๊ธฐ๊ฐ„์„ ์ •ํ™•ํžˆ ์ •์˜ํ•˜๊ธฐ ์–ด๋ ต๋‹ค. ๋”ฐ๋ผ์„œ, ์‹œ๊ฐ„์ด ์ง€๋‚ ์ˆ˜๋ก ์—”ํŠธ๋ฆฌ์˜ ๊ฐ€์น˜๋ฅผ ๋–จ์–ด๋œจ๋ฆฌ๋Š” ๋ฐฉ์‹์„ ํ”ํžˆ ์‚ฌ์šฉํ•œ๋‹ค.
  • ์ด๋Ÿฐ ๋ฐฉ์‹์—์„œ๋Š” ์“ฐ์ง€ ์•Š๋Š” ์—”ํŠธ๋ฆฌ๋ฅผ ์ด๋”ฐ๊ธˆ ์ฒญ์†Œํ•ด์ค˜์•ผ ํ•œ๋‹ค.
  • ScheduledThreadPoolExecutor ๊ฐ™์€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ๋ฅผ ํ™œ์šฉํ•˜๊ฑฐ๋‚˜ ์บ์‹œ์— ์ƒˆ ์—”ํŠธ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ๋ถ€์ˆ˜ ์ž‘์—…์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.
  • LinkedHashMap์€ removeEldestEntry ๋ฉ”์„œ๋“œ๋ฅผ ์จ์„œ ํ›„์ž์˜ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  • ๋” ๋ณต์žกํ•œ ์บ์‹œ๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๋ฉด java.lang.ref ํŒจํ‚ค์ง€๋ฅผ ์ง์ ‘ ํ™œ์šฉํ•ด์•ผ ํ•  ๊ฒƒ์ด๋‹ค.
LinkedHashMap
- HashMap๊ณผ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋ฉด์„œ ์ถ”๊ฐ€๋กœ ์—ฐ๊ฒฐ ๋ชฉ๋ก์„ ํ†ตํ•ด ํ‚ค-๊ฐ’ ์Œ์˜ ์‚ฝ์ž… ์ˆœ์„œ ๋˜๋Š” ์•ก์„ธ์Šค ์ˆœ์„œ๋ฅผ ์œ ์ง€ํ•œ๋‹ค. 
- ์ด๋Ÿฌํ•œ ์ˆœ์„œ ์œ ์ง€ ๊ธฐ๋Šฅ์€ ์บ์‹œ ๊ตฌํ˜„๊ณผ ๊ฐ™์€ ํŠน์ • ์œ ์Šค์ผ€์ด์Šค์—์„œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋œ๋‹ค.

1. ์ˆœ์„œ ๋ณด์žฅ:
- LinkedHashMap์€ ํ‚ค-๊ฐ’ ์Œ์˜ ์‚ฝ์ž… ์ˆœ์„œ๋ฅผ ๊ธฐ์–ตํ•œ๋‹ค.
- ๋”ฐ๋ผ์„œ ๋ฐ˜๋ณต์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งต์„ ์ˆœํšŒํ•  ๋•Œ ํ‚ค-๊ฐ’ ์Œ์ด ์‚ฝ์ž…๋œ ์ˆœ์„œ๋Œ€๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค.

2.์•ก์„ธ์Šค ์ˆœ์„œ ๋ชจ๋“œ:
- LinkedHashMap์€ ์•ก์„ธ์Šค ์ˆœ์„œ ๋ชจ๋“œ๋ฅผ ์„ ํƒ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
- ์ด ๋ชจ๋“œ์—์„œ๋Š” get๊ณผ put ์—ฐ์‚ฐ์ด ์ˆ˜ํ–‰๋  ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น ํ•ญ๋ชฉ์ด ์—ฐ๊ฒฐ ๋ชฉ๋ก์˜ ๋์œผ๋กœ ์ด๋™ํ•œ๋‹ค.
- ์ด ๊ธฐ๋Šฅ์€ ์ตœ๊ทผ์— ์•ก์„ธ์Šคํ•œ ํ•ญ๋ชฉ์„ ๋งต์˜ ๋์— ์œ ์ง€ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, LRU(Least Recently Used) ์บ์‹œ ๊ตฌํ˜„๊ณผ ๊ฐ™์€ ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์œ ์šฉํ•˜๋‹ค.

3.removeEldestEntry ๋ฉ”์„œ๋“œ:
- ์ด ๋ฉ”์„œ๋“œ๋Š” ๋งต์— ์ƒˆ ํ•ญ๋ชฉ์ด ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœ๋œ๋‹ค.
- ์ด ๋ฉ”์„œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์—ฌ ๋งต์˜ ํฌ๊ธฐ๊ฐ€ ํŠน์ • ์ž„๊ณ„๊ฐ’์„ ์ดˆ๊ณผํ•˜๋ฉด ๊ฐ€์žฅ ์˜ค๋ž˜๋œ ํ•ญ๋ชฉ์„ ์ž๋™์œผ๋กœ ์ œ๊ฑฐํ•˜๋Š” ๋กœ์ง์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

import java.util.LinkedHashMap;
import java.util.Map;
// ์บ์‹œ์— ์ƒˆ ์—”ํŠธ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ๋ถ€์ˆ˜์ž‘์—…์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ• ์˜ˆ์ œ
public class Example {
    public static void main(String[] args) {
        // LRU ์บ์‹œ๋กœ ๋™์ž‘ํ•˜๋Š” LinkedHashMap 
        int cacheSize = 5;
        LinkedHashMap<String, String> lruCache = new LinkedHashMap<String, String>(16, 0.75f, true) {
           //true : ์•ก์„ธ์Šค ์ˆœ์„œ ๋ชจ๋“œ(accessOrder) ํ™œ์„ฑํ™”
           @Override
            protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
                return size() > cacheSize;
                //true : ๊ฐ€์žฅ ์˜ค๋ž˜๋œ ํ•ญ๋ชฉ ์ œ๊ฑฐ, false : ์ œ๊ฑฐ์•ˆ๋จ
            }
        };

        for (int i = 1; i <= 10; i++) {
            lruCache.put("key" + i, "value" + i);
        }

        System.out.println(lruCache); // ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ถ”๊ฐ€๋œ 5๊ฐœ์˜ ํ•ญ๋ชฉ๋งŒ ์ถœ๋ ฅ
    }
}

 

 

 

5. ๋ฆฌ์Šค๋„ˆ(listener) ๋˜๋Š” ์ฝœ๋ฐฑ(callback)์—์„œ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ฝœ๋ฐฑ์„ ๋“ฑ๋ก๋งŒ ํ•˜๊ณ  ๋ช…ํ™•ํžˆ ํ•ด์ง€ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ๋ญ”๊ฐ€ ์กฐ์น˜ํ•ด์ฃผ์ง€ ์•Š๋Š” ํ•œ ์ฝœ๋ฐฑ์€ ๊ณ„์† ์Œ“์—ฌ๊ฐˆ ๊ฒƒ์ด๋‹ค.
  • ์ด๋Ÿด ๋•Œ ์ฝœ๋ฐฑ์„ ์•ฝํ•œ ์ฐธ์กฐ(weak reference)๋กœ ์ €์žฅํ•˜๋ฉด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ์ฆ‰์‹œ ์ˆ˜๊ฑฐํ•ด๊ฐ„๋‹ค. (ex. WeakHashMap์— ํ‚ค๋กœ ์ €์žฅํ•˜๋ฉด ๋œ๋‹ค.)

 

import java.util.WeakHashMap;

interface EventListener {
    void onEvent(String event);
}

class EventManager {
    // ๋ฆฌ์Šค๋„ˆ๋ฅผ WeakHashMap์˜ ํ‚ค๋กœ ์ €์žฅํ•˜์—ฌ ์•ฝํ•œ ์ฐธ์กฐ๋ฅผ ์œ ์ง€
    private WeakHashMap<EventListener, Boolean> listeners = new WeakHashMap<>();

    public void registerListener(EventListener listener) {
        listeners.put(listener, Boolean.TRUE);
    }

    public void fireEvent(String event) {
        for (EventListener listener : listeners.keySet()) {
            listener.onEvent(event);
        }
    }
}

public class Example {
    public static void main(String[] args) {
        EventManager manager = new EventManager();

        // ๋ฆฌ์Šค๋„ˆ๋ฅผ ๋“ฑ๋ก
        EventListener listener = event -> System.out.println("Received event: " + event);
        manager.registerListener(listener);

        // ์ด๋ฒคํŠธ ๋ฐœ์ƒ
        manager.fireEvent("Test Event 1");

        // ๋ฆฌ์Šค๋„ˆ ์ฐธ์กฐ๋ฅผ ์ œ๊ฑฐ
        listener = null;

        // ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋ฅผ ํžŒํŠธ๋กœ ์‹คํ–‰
        System.gc();

        // ์ด๋ฒคํŠธ ๋ฐœ์ƒ
        manager.fireEvent("Test Event 2"); // ์ด์ „ ๋ฆฌ์Šค๋„ˆ๋Š” ๋” ์ด์ƒ ์ถœ๋ ฅ๋˜์ง€ ์•Š๋Š”๋‹ค.
    }
}
๋ฐ˜์‘ํ˜•
Comments