-
๊ธฐ์กด์ ์ด๋ ธํ ์ด์ Target ์ข ๋ฅ
- TYPE : ํด๋์ค / ์ธํฐํ์ด์ค / ์ด๋ ธํ ์ด์ / enum / record์ ์ ์ธ๋ถ
- ANNOTATION_TYPE : ์ด๋ ธํ ์ด์ ์ ์ ์ธ๋ถ
- FIELD : ํด๋์ค๋ด์ ๋ด๋ถํ๋์ ์ ์ธ๋ถ
- METHOD : ํด๋์ค๋ด์ ๋ฉ์๋์ ์ ์ธ๋ถ
- PARAMETER : ๋ฉ์๋๋ด์ ํ๋ฆฌ๋ฏธํฐ์ ์ ์ธ๋ถ
- CONSTRUCT : ์์ฑ์์ ์ ์ธ๋ถ
- LOCAL_VARIABLE : ์ง์ญ๋ณ์์ ์ ์ธ๋ถ
- PAKCAGE : ํด๋น ํจํค์ง์ packge-info.java์ ๋ถ์ผ ์ ์๋ค.
-
java8์ ์ถ๊ฐ๋ Target
-
์์ ์ด๋ ธํ ์ด์ ๋ค๊ณผ๋ ๋ค๋ฅด๊ฒ ์ ์ธ ์ฃผ์์ด ์๋ TYPE ์ฃผ์์ด๋ค.
- ์ ์ธ ์ฃผ์ : ์ฃผ์์ฌํญ, ์ฌ์ฉ๋ฐฉ๋ฒ, ์ฌ์ฉ์ฒ ๋ฑ ์ค๋ช
- TYPE ์ฃผ์ : ์ ์ ๊ฐ์ด 0๋ณด๋ค ์ปค์ผ ํ๋ค, null์ด ์๋๋ค ์ ๊ฐ์ ๊ฐ์ ๋ํ ์ ๋ณด ์ ๊ณตํจ์ผ๋ก์จ implements, thorws, new ๊ตฌ์ ์ ์ฌ์ฉํ๊ฑฐ๋ ์ ๋ค๋ฆญ์ ์ฌ์ฉํจ์ผ๋ก์จ ์ธ๋ถ์ ํ๋ก์ ํธ์๋ ์ ์ฉํ ์ ์๋๋ก ํ์ฅํ ๋ฒ์
-
TYPE_PARAMETER : ํ์ ์ ์ธ๋ถ์ ์ฌ์ฉ์ด ๊ฐ๋ฅ
//annotation @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE_PARAMETER) public @interface ParmeterEx { } //class์ ์ฌ์ฉ public class AnnotationStudy <@ParmeterEx T> { public void print( T t){} } //method์ ์ฌ์ฉ public class AnnotationStudy { public <@ParmeterEx T> void print( T t){} } //method์ ์ฌ์ฉ public class AnnotationStudy { public <@ParmeterEx T> void print(T t) throws @ParameterEx SomthingException{} } //BYTE CODE public class study/AnnotationStudy { // compiled from: AnnotationStudy.java @Lstudy/ParmeterEx;() : CLASS_TYPE_PARAMETER 0, null // access flags 0x0 Ljava/lang/String; name // access flags 0x1 public <init>()V L0 LINENUMBER 3 L0 ALOAD 0 INVOKESPECIAL java/lang/Object.<init> ()V L1 LINENUMBER 4 L1 ALOAD 0 LDC "default" PUTFIELD study/AnnotationStudy.name : Ljava/lang/String; RETURN L2 LOCALVARIABLE this Lstudy/AnnotationStudy; L0 L2 0 // signature Lstudy/AnnotationStudy<TT;>; // declaration: this extends study.AnnotationStudy<T> MAXSTACK = 2 MAXLOCALS = 1 // access flags 0x1 // signature <R:Ljava/lang/Object;>()V // declaration: void print<R>() public print()V @Lstudy/ParmeterEx;() : METHOD_TYPE_PARAMETER 0, null
์ปดํ์ผํ๋ฉด์ ํด๋น ํ์ ์ด ๋ฌด์จ ํ์ ์ธ์ง ๋ถ์ํ์ฌ CLASS_TYPE_PARAMETER / METHOD_TYPE_PARAMETER ๋ก ๋ณํํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
ํ์ ์ ์ธ๋ถ์ ์ฌ์ฉ์ด ๊ฐ๋ฅํ Target์ด๋ฏ๋ก ์๋์ ๊ฐ์ด ์ค์ ์ฌ์ฉํ๋ ๋ถ๋ถ์๋ ์ ์ฉํ ์ ์๋ค.
public class AnnotationStudy { public <T> void print(@ParmeterEx T a){} }
-
TYPE_USE : ์ ์ธ๋ถ ๋ฟ๋ง์ด ์๋ ํ์ ์ฌ์ฉ๋๋ ๋ชจ๋ ๊ณณ์ ์ ์ฉ์ด ๊ฐ๋ฅ(ํด๋์ค/์ธํฐํ์ด์ค/๋ด๋ถํ๋/ํ๋ผ๋ฏธํฐ/์ ๋ค๋ฆญ/์ง์ญ๋ณ์ ๋ฑ)
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE_USE) public @interface ParmeterEx { } @ParmeterEx public class AnnotationStudy <@ParmeterEx T>{ @ParmeterEx String name = "default"; @NonNull public <@ParmeterEx R> void print(@ParmeterEx String t, @ParmeterEx R r){ @ParmeterEx int a=1; } } //byte code // class version 61.0 (61) // access flags 0x21 // signature <T:Ljava/lang/Object;>Ljava/lang/Object; // declaration: study/AnnotationStudy<T> public class study/AnnotationStudy { // compiled from: AnnotationStudy.java @Lstudy/ParmeterEx;() @Lstudy/ParmeterEx;() : CLASS_TYPE_PARAMETER 0, null // access flags 0x0 Ljava/lang/String; name @Lstudy/ParmeterEx;() : FIELD, null // access flags 0x1 public <init>()V L0 LINENUMBER 4 L0 ALOAD 0 INVOKESPECIAL java/lang/Object.<init> ()V L1 LINENUMBER 5 L1 ALOAD 0 LDC "default" PUTFIELD study/AnnotationStudy.name : Ljava/lang/String; RETURN L2 LOCALVARIABLE this Lstudy/AnnotationStudy; L0 L2 0 // signature Lstudy/AnnotationStudy<TT;>; // declaration: this extends study.AnnotationStudy<T> MAXSTACK = 2 MAXLOCALS = 1 // access flags 0x1 // signature <R:Ljava/lang/Object;>(Ljava/lang/String;TR;)V // declaration: void print<R>(java.lang.String, R) public print(Ljava/lang/String;Ljava/lang/Object;)V @Lstudy/ParmeterEx;() : METHOD_TYPE_PARAMETER 0, null @Lstudy/ParmeterEx;() : METHOD_FORMAL_PARAMETER 0, null @Lstudy/ParmeterEx;() : METHOD_FORMAL_PARAMETER 1, null L0 LINENUMBER 10 L0 ICONST_1 ISTORE 3 L1 LINENUMBER 11 L1 RETURN L2 LOCALVARIABLE this Lstudy/AnnotationStudy; L0 L2 0 // signature Lstudy/AnnotationStudy<TT;>; // declaration: this extends study.AnnotationStudy<T> LOCALVARIABLE t Ljava/lang/String; L0 L2 1 LOCALVARIABLE r Ljava/lang/Object; L0 L2 2 // signature TR; // declaration: r extends R LOCALVARIABLE a I L1 L2 3 LOCALVARIABLE @Lstudy/ParmeterEx;() : LOCAL_VARIABLE, null [ L1 - L2 - 3 ] MAXSTACK = 1 MAXLOCALS = 4 // access flags 0x9 public static main([Ljava/lang/String;)V L0 LINENUMBER 15 L0 RETURN L1 LOCALVARIABLE args [Ljava/lang/String; L0 L1 0 MAXSTACK = 0 MAXLOCALS = 1 }
๋ฐ์ดํธ ์ฝ๋๋ฅผ ๋ณด๋ฉด TYPE_USE๋ฅผ ์ฌ์ฉํด๋ ์ปดํ์ผ ๊ฒฐ๊ณผ๋ ์ปดํ์ผ๋ฌ๊ฐ ์ ์ ํ ์ด๋ ธํ ์ด์ TARGET์ผ๋ก ๋ฐ๊พธ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE}) @Retention(RetentionPolicy.CLASS) @Documented public @interface NonNull { }
Lombok์ NonNull ์ด๋ ธํ ์ด์ ์ผ๋ก ํด๋น ์ด๋ ธํ ์ด์ ๋ Target๋ฒ์๊ฐ TYPE_USE๊ฐ ํฌํจ๋์ด ์๋ค.
-
-
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface Chicken {
String value() default "ํ๋ผ์ด๋";
}
//error
@Chicken
@Chicken("์๋
")
public class App() {
}๊ธฐ์กด์๋ ์์ ๊ฐ์ด ๊ฐ์ ์ด๋
ธํ
์ด์
์ ๊ฐ์๋ฒ์์ ์ค๋ณตํด์ ์ ์ํ ์ ์์๋๋ฐ java8๋ถํฐ๋ @Repeatable()์ด ์ถ๊ฐ๋์ด ์ค๋ณตํด์ ์ฌ์ฉ์ด ๊ฐ๋ฅํด์ก๋ค.
Reapetable์ ํ๊ฐ์ value๋ฅผ ๊ฐ์ง๊ณ ์๋๋ฐ ์ฌ๊ธฐ์ ์ผ์ข ์ ์ด๋ ธํ ์ด์ ์ปจํ ์ด๋ ์ญํ ์ ํ ์ด๋ ธํ ์ด์ ํด๋์ค๋ฅผ ๋๊ฒจ์ฃผ๋ฉด ํด๋น ์ปจํ ์ด๋์ ์ค๋ณต์ฌ์ฉํ ์ด๋ ธํ ์ด์ ๋ค์ ๋ด๋ ๋ฐฉ์์ผ๋ก ๋์ํ๊ฒ ๋๋ค. ์ด๋ ์ฃผ์ํ ์ ์ด Reapeatable์ value๋ ์ด๋ ธํ ์ด์ ์ ์ปจํ ์ด๋ ์ญํ ์ด๊ธฐ ๋๋ฌธ์ ์ค๋ณตํด์ ์ฌ์ฉํ ์ด๋ ธํ ์ด์ ๋ณด๋ค ์๋ช ์ฃผ๊ธฐ(RetentionPolicy)๊ฐ ๊ธธ์ด์ผ๋ง ํ๋ค.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface ChickenContainer {
Chicken[] value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@Repeatable(ChickenContainer.class)
public @interface Chicken {
String value() default "ํ๋ผ์ด๋";
}
@Chicken("์๋
")
@Chicken("๋ง๋๊ฐ์ฅ")
public class App {
public static void main(String[] args) {
ChickenContainer chickenContainer = App.class.getAnnotation(ChickenContainer.class);
Arrays.stream(chickenContainer.value()).forEach(c -> {
System.out.println(c.value());
});
}
}
//print
์๋
๋ง๋๊ฐ์ฅ
//bytecode
// class version 59.0 (59)
// access flags 0x21
public class javaStudy/Example {
// compiled from: Example.java
@LjavaStudy/ChickenContainer;(value={@LjavaStudy/Chicken;(value="\uc591\ub150"), @LjavaStudy/Chicken;(value="\ub9c8\ub298\uac04\uc7a5")})
// access flags 0x19
public final static INNERCLASS java/lang/invoke/MethodHandles$Lookup java/lang/invoke/MethodHandles Lookup
// access flags 0x1
public <init>()V
L0
LINENUMBER 7 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
RETURN
L1
LOCALVARIABLE this LjavaStudy/Example; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x9
public static main([Ljava/lang/String;)V
L0
LINENUMBER 9 L0
LDC LjavaStudy/Example;.class
LDC LjavaStudy/ChickenContainer;.class
INVOKEVIRTUAL java/lang/Class.getAnnotation (Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
CHECKCAST javaStudy/ChickenContainer
ASTORE 1
L1
LINENUMBER 10 L1
ALOAD 1
INVOKEINTERFACE javaStudy/ChickenContainer.value ()[LjavaStudy/Chicken; (itf)
INVOKESTATIC java/util/Arrays.stream ([Ljava/lang/Object;)Ljava/util/stream/Stream;
INVOKEDYNAMIC accept()Ljava/util/function/Consumer; [
// handle kind 0x6 : INVOKESTATIC
java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
// arguments:
(Ljava/lang/Object;)V,
// handle kind 0x6 : INVOKESTATIC
javaStudy/Example.lambda$main$0(LjavaStudy/Chicken;)V,
(LjavaStudy/Chicken;)V
]
INVOKEINTERFACE java/util/stream/Stream.forEach (Ljava/util/function/Consumer;)V (itf)
L2
LINENUMBER 13 L2
RETURN
L3
LOCALVARIABLE args [Ljava/lang/String; L0 L3 0
LOCALVARIABLE chickenContainer LjavaStudy/ChickenContainer; L1 L3 1
MAXSTACK = 2
MAXLOCALS = 2
// access flags 0x100A
private static synthetic lambda$main$0(LjavaStudy/Chicken;)V
L0
LINENUMBER 11 L0
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
ALOAD 0
INVOKEINTERFACE javaStudy/Chicken.value ()Ljava/lang/String; (itf)
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L1
LINENUMBER 12 L1
RETURN
L2
LOCALVARIABLE c LjavaStudy/Chicken; L0 L2 0
MAXSTACK = 2
MAXLOCALS = 1
}ChickenConatiner ์ด๋ ธํ ์ด์ ์ ์์ฑํ์ฌ Chicken ์ด๋ ธํ ์ด์ ๋ค์ value๋ก ํ ๋นํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
MethodHandles$Lookup๋ผ๋ ์ด๋ฆ์ ํด๋์ค๋ก innerClass๊ฐ ๋ง๋ค์ด์ง๋ ๊ฒ์ ๋ณผ ์ ์๋๋ฐ ์ด๋ ๋ฉ์๋ ํธ๋ค์ ์์ฑํ๊ธฐ์ํ factory class๋ก ChickenContainer์ value()์ธ Chicken[]์ ์ ๊ทผํ๊ธฐ์ํ class
Arrays.parallerSort()๊ฐ ์ถ๊ฐ๋์ด ๋ถ์ฐ๋์ด ์ ๋ ฌ์ด ๊ฐ๋ฅํ๋ค.
public class Example {
public static void main(String[] args) {
int size = 1500;
int[] numbers = new int[size];
Random random = new Random();
IntStream.range(0,size).forEach(i -> numbers[i] = random.nextInt());
long start = System.nanoTime();
Arrays.sort(numbers);
System.out.println("time : " + (System.nanoTime() - start) );
IntStream.range(0,size).forEach(i -> numbers[i] = random.nextInt());
start = System.nanoTime();
Arrays.parallelSort(numbers);
System.out.println("time : " + (System.nanoTime() - start) );
}
}JVM์ ์ฌ๋ฌ ๋ฉ๋ชจ๋ฆฌ ์์ญ ์ค์ PermGen ๋ฉ๋ชจ๋ฆฌ ์์ญ์ด ์์ด์ง๊ณ Metaspace ์์ญ์ด ์๊ฒผ๋ค.
- Heap ์์ญ์ ์ํจ
- permanent generation, ํด๋์ค ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ด๋ ๊ณณ.
- ๊ธฐ๋ณธ ๊ฐ์ผ๋ก ๊ณ ์ ๋๊ณ ์ ํ๋ ํฌ๊ธฐ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
- PermGen์ด๊ธฐ ์ฌ์ด์ฆ ์ค์ :
-XX:PermSize=N - PermGen ์ต๋ ์ฌ์ด์ฆ ์ค์ :
-XX:MaxOermSize=N - Old/Eden ์์ญ๋ณด๋ค ์ ์ ๋ฉ๋ชจ๋ฆฌ์ฌ์ด์ฆ๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ os bit, jdk ๋ฒ์ ๋ณ๋ก ๋ค๋ฅด๋ค.
- ๊ณ ์ ๋ ํฌ๊ธฐ๋ฅผ ๊ฐ์ง๊ธฐ ๋๋ฌธ์ ํด๋์ค๋ฅผ ๊ณ์ํด์ ๋ง๋ค๊ฒ ๋๋ฉด GC๊ฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ๋ฆฌํด๋ PermGen์ฌ์ด์ฆ๋ฅผ ๋์ด์๋ฉด memory out ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
- ํด๋์ค ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ด๋ ๊ณณ
- Heap์์ญ์ด ์๋๋ผ Native ๋ฉ๋ชจ๋ฆฌ ์์ญ์ด๋ค.
- ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ ํ๋ ํฌ๊ธฐ๋ฅผ ๊ฐ์ง๊ณ ์์ง ์๋ค. (๊ฒ์ ๋์ด๋ ์ ์๋ค.)
- ๊ณ์ํด์ ๋์ด๋ ์ ์๊ธฐ ๋๋ฌธ์ ์์นซ ์๋ชปํ๋ฉด os์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ชจ๋ ์ก์๋จน์ด ์๋ฒ ์์ฒด๊ฐ ๋ค์ด๋ ์ ์๋ค.
- java8๋ถํฐ๋ PermGen ๊ด๋ จ java์ต์ ์ ๋ฌด์
- Metaspace ์ด๊ธฐ ์ฌ์ด์ฆ ์ค์ :
-XX:MetaspaceSize=N - Metaspace ์ต๋ ์ฌ์ด์ฆ ์ค์ :
-XX:MaxMetaspaceSize=N
์์ํ ๋๋งํด๋ 5์ฃผ๊ฐ ๋๊ฒ ๊ธด ๊ฒ์ฒ๋ผ ๋๊ปด์ก๊ณ , Java8ํ๋๋ฅผ ๋๋ฌด ์ค๋๋๋๊ฒ ์๋๊ฐ ์ถ์๋๋ฐ ๋ง์ ์งํํด๋ณด๋ ๋ถ๋์ด ์ ๋ง ์ ์ ํ์ผ๋ฉฐ ์คํ๋ ค ์๊ฐ์ด ๋ถ์กฑํ ๋๋์ด์๋ค.
์ด๋ค ๊ธฐ๋ฅ๋ถํฐ๊ฐ java8์ ๊ธฐ๋ฅ์ธ์ง ๊ตฌ๋ถ์ด ์๊ฐ๋๋ฐ ์ด๋ฒ ๊ธฐํ์ ํ์คํ ์๊ฒ ๋์๊ณ ํนํ ๋๋ค๋ถ๋ถ์ ๋ง์ด ์ฌ์ฉํ ๊ฒ ๊ฐ๋ค.
๋ค์ ์ฃผ์ ๋ ๋์์ธํจํด์ธ๋ฐ ๊ธฐ๋๊ฐ ๋๋ค.