일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 히든 스토리
- 칭기즈칸의 위대한 장군 수부타이
- 레퍼런스 복사
- 쿠버네티스
- 도파민형 인간
- 수부타이
- try width resources
- CSS
- try-with-resources
- Infresh
- 월칙
- node
- HTML
- java
- kubernetes
- 공헌감
- 모두가 기다리는 사람
- 이펙티브 자바
- 과제의 분리
- docker
- 참조 계수
- colllection
- 아웃풋법칙
- apache kafka
- 뉴 컨피던스
- ESG
- 비메모리 자원
- Container
- 부자의그릇
- sentry
- Today
- Total
Hi
얕은 복사, 깊은 복사, 참조 계수(Reference Counting) 본문
a : Data
b = a // copy
복사 정책 2가지
1. 레퍼런스 복사(얕은 복사)
* 장점: 속도가 빠르고, 메모리도 덜 쓴다.
* 단점: 객체의 파괴 시점을 결정할 수 없다.
=> 댕글링 포인터
해결방법: 참조 계수에 의한 객체 수명 관리
2. 값 복사(깊은 복사)
* 장점: 객체의 파괴 시점을 결정할 필요가 없다.
* 단점: 데이터의 크기가 클 수록 속도가 느려지고,
그만큼의 메모리도 소모해야 한다.
Reference Counting
=> 참조 계수
객체의 생성과 소멸
=> StringBuilder - 문자열이 수정될 때마다 객체의 생성을 만드는 것을 방지
Integer.valueOf - 같은 숫자는 객체를 생성하지 않고 참조할 수 있도록 한다.
3. 참조 계수 관리하는 2가지 방법
1. GC : Java, Go, C#, Javascript
=> '런타임(dynamic, virtual)'에 별도의 프로그램이 객체의 수거를 담당한다.
장점: 런타임에 GC가 판단해서,수거하므로 유연하게 동작한다.
단점: GC가 발생하면, 프로그램의 성능이 저하된다.
2. ARC : Objective-C, Swift
=> '컴파일 타임'(static)에 객체의 참조 계수를 관리하는
코드를 삽입한다.
장점: 빠르게 동작한다.
단점: 제대로 된 코드를 작성하지 않으면,
정상적으로 객체의 메모리가 수거되지 않는다.
GC가 수거하는 대상
=> 참조 계수가 0인 객체
참조 계수를 사용했을 때 메모리 누수가 발생할 수 있다.
=> 순환 참조에서 발생한다.
자원(Resource)
메모리 자원: 객체 - 참조 계수 - GC
비메모리 자원? (File 등)
: 비메모리 자원은 반드시 명시적인 종료 메소드를 통해 해지해주어야 한다.
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
// 객체가 GC에 의해서 수거되는 시점에 호출되는 메소드 - finalize
class Image {
byte[] data = new byte[1024 * 1024]; // 4M
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("이미지 파괴");
}
}
class Node {
int data;
Node next;
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("Node finalized");
}
}
public class Program_0322 {
public static void foo() {
Node a = new Node();
Node b = new Node();
a.next = b; // 순환참조
b.next = a;
}
/*
public static void main(String[] args) throws Exception {
foo();
System.gc();
TimeUnit.SECONDS.sleep(1000);
}
*/
// 강한 참조(Strong Reference)
// : GC의 수거 대상이 되지 않는다.
// 가용한 메모리가 없을 경우, Out Of Memory가 발생한다.
// 약한 참조
// 1. SoftReference
// => Out of Memory에 가까워질 경우 수거 되는 대상.
// 2. WeakReference
// => GC가 발생하면 수거된다.
public static void main(String[] args) throws InterruptedException {
// ArrayList<Image> images = new ArrayList<>();
ArrayList<WeakReference<Image>> images = new ArrayList<>();
for (int i = 0 ; i < 1000000000 ; ++i) {
images.add(new WeakReference<>(new Image()));
TimeUnit.MICROSECONDS.sleep(1000);
}
}
/*
public static void main(String[] args) {
// 1. 객체가 생성되면, 참조 계수는 1이다.
Image image1 = new Image();
// 2. 객체 참조가 복사되면, 참조 계수는 증가한다.
Image image2 = image1;
// 3. 객체 참조가 사라지면, 객체는 파괴된다.
image1 = null; // refCount: 1
image2 = null; // refCount: 0
// 4. GC를 무조건 실행하는 것이 아니다.
// System.gc();
System.out.println("Program end");
}
*/
}
'Programming > Java' 카테고리의 다른 글
hashCode / equals (0) | 2018.04.02 |
---|---|
Reflection (0) | 2018.04.02 |
Exception(예외)와 try-with-resources (0) | 2018.03.29 |
vi & 터미널(terminal) 명령어 (0) | 2018.03.29 |
비메모리 자원이 있는 객체와 Try with Resources (0) | 2018.03.29 |