WonYong-Jang / Development-Process

It is where I record the error fixes or learning during the development process.
0 stars 1 forks source link

Development-Process

It is where I record the error fixes or learning during the development process.

자바 최적화 교재 Study

Java 의 Stack 과 Heap

Stack

Heap

주의) Heap 영역에 있는 데이터는 함수 내부에서 파라미터로 받아서 변경하고
함수 호출이 종료된 시점에 변경 내역이 반영되는 것을 확인 !!

List<String> list = new ArrayList<>();
solve(list);
==> solve 함수에서 list 를 변경하면 그대로 반영됨! 힙영역에 있으므로 !

주의 ) 아래와 같이 Integer는 heap 영역에서 관리하는 Object 타입인데 변경되지 않는 이유는 String과 동일하게 불변객체(immutable)이기 때문

Integer a = 10;
solve(a); 
=> solve 함수에서 값을 변경하면 바뀌지 않는다!!!

=> 실행 순서는 a가 가르키는 10은 heap 에 생성되지만 solve 라는 함수로
param = 10 으로 넘어갈때 Wrapper class 는 기존에 레러펀스하고 있던 값을
새롭게 생성된 오브젝트를 만들기 때문에 함수가 끝나고 나면 변경된 값 pop 되기때문 !!!

JVM

스크린샷 2020-01-23 오후 7 44 03

Java Compiler

Class Loader

Execution Engine

GC

String url = "abc";
url += "def";

=> + 하는 순간 새롭게 "abcdef" 라는 객체를 만들고 url이 레퍼런스
==> 처음 "abc" 오브젝트는 Unreachable 오브젝트라 하고 GC의 대상!!

Minor GC와 Major GC

Reachability

Runtime Data Areas(JVM 메모리)

GC 로깅

JVM 옵션 정리

-verbose:gc                     //
-XX:+PrintCommandLineFlag       // 어떤 가비지 컬렉터를 사용하는지 볼수 있음
-Xms
-Xmx

-Xmx16m -verbose:gc -XX:+PrintCommandLineFlags // OutofMemoryError를 빨리 내기 위해 jvm 옵션 설정

1) 프로그램이 메모리 부족으로 죽는 경우

public class ListGCTest {
    public static void main(String[] args) throws Exception {
        List<Integer> li = IntStream.range(1, 100).boxed().collect(Collectors.toList());
        for (int i=1; true; i++) {
            if (i % 100 == 0) {
                Thread.sleep(100);
            }
            IntStream.range(0, 100).forEach(li::add);
        }
    }
}

2) 가비지 컬렉터가 열일하여 프로그램이 죽지 않는 경우

public class ListGCTest {
    public static void main(String[] args)throws Exception {
        List<Integer> li = IntStream.range(1, 100).boxed().collect(Collectors.toList());
        for (int i=1; true; i++) {
            if (i % 100 == 0) {
                li = new ArrayList<>();
                Thread.sleep(100);
            }
            IntStream.range(0, 100).forEach(li::add);
        }
    }
}

메모리 구성 Metaspace 와 Heap

1) Metaspace

1-1) PermGen 은 자바 7까지 메타데이터를 저장하던 영역이였고 Heap의 일부

==> 자바 8부터 클래스들은 모두 힙이 아닌 네이티브 메모리를 사용하는 Metaspace에 할당 됨

public class MetaspaceTest {
    static javassist.ClassPool cp = javassist.ClassPool.getDefault();

    public static void main(String[] args) throws Exception{
        for (int i = 0; ; i++) {
            if (i % 1000 == 0) Thread.sleep(100);
            Class c = cp.makeClass("test" + i).toClass();
        }
    }
}

2) Heap - Old & Young ( Eden, Survivor)

가비지 컬렉션 프로세스

용어 정리

JVM 모니터링과 툴링

VisualVM

메모리 누수 해결책

1) WeakReference vs StrongReference

2) WeakReference 구현

WeakReference wr;

public String getFileContent(String filename) {
    // WeakReference 에 의해 파일 내용이 보존되어 있는지 체크
    String fileContent = (wr != null) ? wr.get() : null;

    if(fileContent == null) {
        // 글 내용이 비었으면 파일 이름으로 내용을 읽어와 채워준다.
        fileContent = fileToString(filename);
        // 채워진 글 내용을 WeakReference 에 저장한다.
        wr = new WeakReference(fileContent);
    }
    return fileContent;
}

참고 : https://yaboong.github.io/java/2018/06/09/java-garbage-collection/