DevJong12

22.05.09 F-Lab멘토링 본문

Java,Spring/F-Lab

22.05.09 F-Lab멘토링

Jong12 2022. 5. 11. 19:50
728x90

Tech

일단 Stack과 힙부터...더 딥하게... 

https://yaboong.github.io/java/2018/05/26/java-memory-management/

 

[loop를 사용하게 될 경우 Garbage Collector의 실행관점에서 조심해야 할 이유]

일단 이문제는 가비지 컬렉터가 해당 값을 현재 참조를 하고 있는지 안하고 있는지 판단을 하는 방법에 대해서 부터 찾아봐야 할 것 같다...

 

음.. 이문제를 처음에는 Stack메모리, Heap메모리를 관련한 부분으로 생각을 해보려고 했다.

근데 그냥 단순하게 무한루프로 반복문을 탈출하지 못하는 상황을 생각해보면 되었던게 아닐까 싶다.

 

루프를 반복하며, 탈출을 못하게 될 경우 지속적으로 해당 반복문이 실행이 될것이고,

그 의미는 프로세스가 끝나지도 않으며 많은 리소스의 활용이 끝나지 않고 발생을 하면서 OOM을 불러 일으키게 된다.

 

근데 여기서 선언하는게 객체를 선언한 이후에 그 객체 안에 static변수가 존재해 버린다면?

1.8이후 버전이라면 모르겠다.. 하지만 1.7이전 버전이라면? GC는 해당 객체들에 대해서 포함이 안되지 않을까 싶다.

 

이건 추측의 영역이고, 확인을 어떻게 해야할 지 모르겠다.... 생각을 해보자..

 

 

[배열을 toString했을 경우 어떠한 값이 출력이 될지, 내부 데이터를 출력할 방법은 어떻게 해야 할 지]

아래의 코드는 Object에 선언이 되어 있는 소스 코드

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

위를 이용해 아래 예제를 만듬

Integer [] a = new Integer[]{1,2,3,4,5};
//[Ljava.lang.Integer;@4554617c
System.out.println(a.toString());

int [] a1 = new int[]{1,2,3,4,5};
//[I@74a14482
System.out.println(a1.toString());

String [] b = {"abc","def","ghi"};
//[Ljava.lang.String;@1540e19d
System.out.println(b.toString());

//[Lc.flab.month5.week2.TestVO;@677327b6
TestVO[] c = {new TestVO("a"), new TestVO("b"), new TestVO("c")};
System.out.println(c.toString());

//c.flab.month5.week2.TestVO@14ae5a5
System.out.println(new TestVO("d").toString());

주석이 결과값이다.

 

각 항목별로 찍히는 값들 

boolean     Z
byte     B
char     C
class or interface     Lclassname;
double     D
float     F
int     I
long     J
short     S
 String.class.getName()
     returns "java.lang.String"
 byte.class.getName()
     returns "byte"
 (new Object[3]).getClass().getName()
     returns "[Ljava.lang.Object;"
 (new int[3][4][5][6][7][8][9]).getClass().getName()
     returns "[[[[[[[I"
 

[의 경우에는 배열의 깊이.. 즉 [(배열) + 클래스명 + 해시코드값으로 되는 것...

https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getName--

위의 링크에 해당 부분에 대한 설명이 잘되있다.

 

내부데이터를 출력할 방법은 생각나는건..

1. 반복문 (Arrays.toString()포함, 해당 메소드도 안에서 반복문이다..)

2. asList이후 List를 stream으로 출력하는건데 굳이 두번의 번거로운 과정을 거쳐야 하나 싶다..

 

 

[static 키워드란 무엇이며 Garbage Collector관점에서 조심히 사용해야 할 이유]

  • static란?
    • 필드, 메소드의 소속을 클래스로 제한하는 키워드로 선언이 된 변수, 메소드를 '정적 변수(클래스 변수)', '정적 메소드(클래스 메소드)'라 칭한다.
    • 클래스 변수, 메소드의 경우의 저장 장소
      • Method Area (JDK 1.7 이전)
        • 클래스 변수
          • 기본형의 경우에는 Method Area에 그대로 저장이 됨
          • 참조형의 경우에는 레퍼런스 변수로 저장이 되며 실제 인스턴스는 Heap영역의 Permanent 영역에 저장이 된다.
      • metaspace 또는 Heap메모리 (JDK 1.8)
    • 클래스 로드가 class를 실행하면서(JVM을 실행하며) 메모리에 할당이 됨  
  • Garbage Collector관점에서 조심해야 할 이유
    • 1.7 이전이라면 GC의 관리가 안되기 떄문에 참조를 하지 않더라도 삭제가 불가능 하다 보니 메모리의 효율적인 관리가 이루어지지 않음
    • 심각한 경우 메모리에 계속 할당만 이루어지면 메모리 누수로 인하여 시스템 자체가 돌아갈 수 없는 상태가 될 수 있음.
    • 1.8 이후는 GC의 관리대상이긴 하기 때문에 참조를 삭제해 줄 수 있는 전략만 잘 구상하면 관리는 가능해 보인다..
  • JDK 1.7이전 vs JDK1.8 이후 static
    • JDK 1.7 이전
      • Heap 메모리 구조
        • New Generation
        • Old Generation
        • Permanent Generation
      • Permanent영역에 메타데이터, 정적변수(static)등이 저장이 된다.
      • GC의 대상에서 제외가 됨
    • JDK 1.8 이후
      • Heap 메모리 구조
        • New Generation
        • Old Generation
      • 힙 외부에 새로 생긴 공간
        • MetaSpace(Native Area)
      • 1.7과 비교시 Permanent가 삭제되고 Metaspace가 힙 외부에 생겼으며 해당공간으로 이동한 것도 있으나 다른 장소로 저장되는 장소가 변경되는게 있다.
        • Native Memory로 저장공간의 변경
          • class meta-data
        • Heap메모리로 변경
          • interned Strings(String Constant pool)
          • class statics

결론 : 1.8 이후 부터는 GC의 관리에 포함이 됨. 하지만 참초를 잃어야 GC관리에 포함이 되는 부분이라 그럴 경우가 대부분 없기에 문제는 없어 보인다..

실제 JDK에 정리가 되어있다
The proposed implementation will allocate class meta-data in native memory and move interned Strings and class statics to the Java heap.

https://openjdk.java.net/jeps/122

[static 블록은 어떤 경우 사용해야 하며, 단점은 무엇이 있을지]

  • static 블록
    • 클래스가 처음으로 사용이 될 때 단 한번만 실행이 되는 코드영역
    • 생성자보다 먼저 사용이 되며 이후 해당 클래스를 호출할 경우에는 해당 코드를 실행하지 않는다.
      • 인스턴스를 위한 블록도 존재한다  static이란 단어만 뺴면 된다.
    • 인스턴스 변수나 메소드, this에 대한 키워드의 사용이 불가능하다.
  • 사용되는 경우?
    • 클래스 변수의 초기화, 싱글톤 패턴에서 사용하면 유용할 것 같다 
  • 단점..?
    • 자원의 관점으로 보지않고 불편함을 관점으로 보니, 인스턴스 변수나 메소드의 사용이 불가능한 점이 단점이지 않을까 싶다.
    • 해당 부분을 해결하고자 모든 변수나 메소드를 클래스 변수로 선언하게 되면 메모리 관리를 비롯해서 전체적인 부분에 문제가 된다는 부분
  •  

 

[객체를 복사하는 방법에 '얕은복사'와 '깊은 복사'가 존재한다. 두개의 차이점?]

  • 얕은 복사 (Shallow Copy)
    • 래퍼런스 변수를 새로 생성하고 해당 주소값을 가리키는 복사
      • 기본형 값을은 그대로 복사를 하지만 참조형 변수는 같은 주소값을 가리키는걸 의미
  • 깊은 복사 (Deep Copy)
    • 아얘 새로운 인스턴스를 생성하여 내용을 복사한다.
      • 기본형값들은 얕은복사와 마찬가지로 그대로 복사가 되지만 레퍼런스 변수의 경우 변수가 참조하는 객체에 대해서도 새로 복사하는것을 의미

 

[접근제어자의 종류와 의미]

  • Public 
    • 접근가능 범위  : 같은 클래스, 같은 패키지, 상속받은 클래스, Import한 클래스
  • protected
    • 접근가능 범위 : 같은 클래스, 같은 패키지, 상속받은 클래스
  • Default (package private)
    • 접근가능 범위 : 같은 클래스, 같은 패키지
  • private
    • 접근가능 범위 : 같은 클래스

 

[Override와 Overload의 차이점]

아..ㅋㅋ...;;;;;;아;;;ㅋㅋㅋㅋㅋ;;;;

  • Overload
public class Overload {

    public Overload() {
    }

    public Overload(String name) {
    }

    public Overload(String name, String email) {
    }

}
  • Override
public class ParentOverride {
    public void overrideSample(String a) {
    }
}

public class ChildOverride extends ParentOverride {
    @Override
    public void overrideSample(String a) {
        System.out.println("ㅋㅋㅋㅋ;;;");
    }
}

 

 


ETC

[깃허브 레쥬메]

 

[코드컨벤션]

레쥬메부터 작업하느라 시간될때 꼭 읽는걸로..

https://www.thoughtco.com/using-java-naming-conventions-2034199

https://www.oracle.com/java/technologies/javase/codeconventions-namingconventions.html

 

 

728x90

'Java,Spring > F-Lab' 카테고리의 다른 글

22. 06. 20 F-Lab 멘토링  (0) 2022.06.27
22. 05. 30 F-Lab 멘토링  (0) 2022.06.12
22.05.24 F-Lab멘토링  (0) 2022.05.30
22.05.16 F-Lab멘토링  (0) 2022.05.18
22.05.04 F-Lab멘토링  (0) 2022.05.05
Comments