์๋ฐ์ String๊ณผ Constant Pool
by JiwonDev
Java์ฝ๋๋ฅผ ์ปดํ์ผํ๋ฉด ํด๋์ค๋จ์ ๋ฐ์ดํธ์ฝ๋(.class)๋ก ๋ณํ๋๋ค. ๊ทธ๋ฆฌ๊ณ ํด๋น ๋ฐ์ดํธ ์ฝ๋๋ฅผ JVM์ ์คํ์ํค๋ฉด Static(Method), Heap, Stack๋ก ๋๋ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํ๋ค.
๊ทธ ์ค Method Area (=Static Area)์์๋ ๊ฐ ํด๋์ค ๋ณ๋ก ๋ค์๊ณผ ๊ฐ์ ๊ณ ์ ์ ๋ณด๋ฅผ ์ ์ฅํฉ๋๋ค. ์ ์ ๊ณต๊ฐ์ด๋ผ๋ ์ด๋ฆ ๋ต๊ฒ ํ๋ก๊ทธ๋จ์ด ์ข ๋ฃ ๋ ๋๊น์ง ๋ฉ๋ชจ๋ฆฌ์ ๋จ์์์ต๋๋ค. (์ด ์์ญ์์๋ GC๊ฐ ๋์ํ์ง ์์ต๋๋ค.)
- file data(ํ๋ ๋ฐ์ดํฐ) : ๋ฉค๋ฒ ๋ณ์์ด๋ฆ, ํ์ , ์ ๊ทผ์ ์ด์๋ฑ์ ๋ฉํ์ ๋ณด
- method data(๋ฉ์๋ ๋ฐ์ดํฐ) : ๋ฉ์๋ ์ด๋ฆ, ๋ฆฌํดํ์ , ๋งค๊ฐ๋ณ์, ์ ๊ทผ์ ์ด์๋ฑ์ ๋ฉํ์ ๋ณด
- constructor(์์ฑ์) : ์์ฑ์ ๋ฉ์๋์ ๊ดํ ์ ๋ณด.
- static ๋ณ์(Class ๋ณ์) : ๋ชจ๋ ๊ฐ์ฒด๊ฐ ๊ณต์ ํ ์ ์๋ ์ ์ ํด๋์ค ๋ณ์.
- runtime constant pool (๋ฐํ์ ์์ ํ)
#์์์ ๋ฆฌํฐ๋(literal)
์์์ ๋ฆฌํฐ๋์ ํท๊ฐ๋ฆด ์ ์๋๋ฐ, ์์๋ '์ด๊ธฐํ ์ดํ ๊ฐ์ด ๋ณํ์ง ์๋ ์' ์ด๋ค. ๋ณ์๋ฅผ ์ ์ธ ํ ๋ final ํค์๋๋ฅผ ์ด์ฉํด ์์๋ก ๋ง๋ค ์ ์๋ค.
final int DAY_OF_WEEK = 7; // ์ฐธ๊ณ ) ๊ฐ๋ฅํ๋ฉด ์์๊ฐ์ get ๋ฉ์๋๋ก ์ ๊ณตํ๋๊ฒ ์ข์ต๋๋ค.
๋ฆฌํฐ๋๋ ์์์ ์ผ์ข ์ธ๋ฐ, ๋ง ๊ทธ๋๋ก ์ ์ธ์์ด ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋, ๋ฌธ์ ๊ทธ๋๋ก์(=๋ฆฌํฐ๋ํ) ์์๋ฅผ ์๋ฏธํ๋ค. immediate value ๋ผ๊ณ ํ๊ธฐ๋ ํ๋ค.
3
"HEllO"
3.213
'H'
๋ณ์๋ก ์ ์ธํ์ง ์๊ณ ๋ฐ๋ก ์์๋ก ์ฌ์ฉํ๋ ๊ฐ๋ค๋ ๊ณ ์ ์ ๋ฐ์ดํฐ ํ์ ์ ๊ฐ์ง๋ค.
์ฐธ๊ณ ๋ก ๋ฆฌํฐ๋ ๋ค์ (L, F, D)๊ฐ์ ํค์๋๋ฅผ ๋ถ์ฌ ๋ช ์์ ์ผ๋ก ํด๋น ๋ฆฌํฐ๋์ ํ์ ์ ์ง์ ํด์ค ์ ์๋ค.
object.setNumber(3) // ๋ฆฌํฐ๋ '3'์ ์๋ฃํ์ int์ด๋ค.
object.setName("Hello") // ๋ฆฌํฐ๋ "Hello"์ ํด๋์ค๋ String์ด๋ค.
object.setNumber(3.0) // ๋ฆฌํฐ๋ '3.0'์ ์๋ฃํ์ int..? float..? double..?
object.setNumber(3.0F) // ์ด๋ ๊ฒ ๋ช
์์ ์ผ๋ก Floatํ ์ด๋ผ๊ณ ์ ํด ์ค ์ ์๋ค.
int a = 1 // ์์์ ์ด ์์ผ๋ฉด intํ ๋ฆฌํฐ๋์ด๋ค. ๋ฐ๋ก ๋ฆฌํฐ๋ ํ์๋ฅผ ํ์ง ์์๋ ๋๋ค.
boolean b = true // boolean์ ๊ฐ์ด true, false 2๊ฐ๋ฐ์ ์์ด ๋ฐ๋ก ๋ฆฌํฐ๋ ํ์๋ฅผ ์ํด๋ ๋๋ค.
// ์ค์ ๋ฆฌํฐ๋์ ์ฌ์ฉํ ๋๋ ๋ฐ๋์ ๋ช
์์ ์ผ๋ก ํ์ํด์ฃผ์.
long count = 10000L;
float f1 = 2.3F;
double d1 = 5.6D;
# ์ฐธ์กฐํ(Reference)
ํด๋์ค๋ฅผ ์ ์ํ๊ณ new ํค์๋๋ฅผ ํตํด ๊ฐ์ฒด๋ฅผ ์์ฑ ํ ์ ์๋ค.
์๋ฐ์์๋ ๊ธฐ๋ณธ ์๋ฃํ์ ์ ์ธํ ๋ชจ๋ ๊ฒ์ ์ฐธ์กฐํ์ผ๋ก ์ฌ์ฉํ๋ค. ์คํดํ์ง ๋ง์์ผ ํ๋๊ฒ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ์ ๊ฐ์ง๊ณ ์๋๊ฒ ์๋๋ผ ์ฌ๋ณผ(=์ด๋ฆ)๋ง ๊ฐ์ง๊ณ ์๋ค. ์ฌ๋ณผ์ ์ด์ฉํด์ ์คํํ๋ ์์ ์ JVM์ด ํด๋น ์ฌ๋ณผ์ด ์ ์ฅ๋์ด์๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ ์ ๊ทผํ๋ค.
//ํด๋์ค์ด๋ฆ ๋ ํผ๋ฐ์ค๋ช
= new ํด๋์ค์ด๋ฆ();
MadPlay instance = new MadPlay();
# String ํด๋์ค
์๋ฐ์์๋ ๋ฌธ์์ด์ด ํด๋์ค๋ก ์ ๊ณต๋์ด์ง๋ค. ํ์ง๋ง String ๊ฐ์ฒด์ ๊ฒฝ์ฐ ์์ธ์ ์ผ๋ก new ํค์๋ ์์ด ๋ฆฌํฐ๋๋ก ์์ฑํ ์ ๋ ์๋๋ฐ, ์ด๋ฅผ ๋ฌธ์์ด ๋ฆฌํฐ๋ ์์ฑ ๋ฐฉ์์ด๋ผ๊ณ ํ๊ณ new ํค์๋๋ฅผ ์ฌ์ฉํ ๊ฒ๊ณผ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฌ ์ฅ์๊ฐ ๋ฌ๋ผ์ง๋ค.
// ๋ค๋ฅธ ๊ฐ์ฒด์ ๋ง์ฐฌ๊ฐ์ง๋ก Heap ์์ญ์ ํ ๋น๋๋ค.
String str1 = new String("madplay");
// ์คํธ๋ง ์์๊ฐ์ผ๋ก ๊ด๋ฆฌ๋๋ค. String Constant Pool ์ด๋ผ๋ ์์ญ์ ์ ์ฅ๋๋ค.
String str2 = "madplay";
String str3 = "madplay"; // ๊ธฐ์กด "madplay" ์์ ์ฌํ์ฉ. str 2์ด๋ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฐธ์กฐ
String str4 = new String("madplay"); // ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑ. str1์ด๋ ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ์ฐธ์กฐ
์ฐธ๊ณ ๋ก String Constant Pool์ ๊ธฐ์กด์๋ ์์๊ฐ ์ ์ฉ ๋ฉ๋ชจ๋ฆฌ์ (Perm ์์ญ) ๋ฐ๋ก ์ ์ฅ๋์ด์ก๋๋ฐ, ๋ฐํ์์ค ๋ฉ๋ชจ๋ฆฌ ์ฆ๊ฐ๋ก ์ธํ OutOfMemory ์์ธ๋ฅผ ๋ฐ์์ํฌ ์ ์์ด Java7 ์ดํ๋ก๋ ๊ฐ์ฒด์ ํจ๊ป Heap ๋ฉ๋ชจ๋ฆฌ์์ญ์์ ๊ด๋ฆฌํ๊ณ ์๋ค.
# ๋ฌธ์์ด ์กฐ์์ StringBuilder๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ์ด์
์์ 2๊ฐ์ง ํน์ง ๋๋ถ์ ์์ ์คํธ๋ง ๋ง์ ( "Hello" + "Hi" ) ์ ๊ฒฝ์ฐ ์ฑ๋ฅ์ด ์๋นํ ๊ตฌ๋ฆฌ๋ค.
- ์คํธ๋ง์ด ์์๊ฐ์ธ ๊ฒฝ์ฐ ๊ฐ์ฒด๋ฅผ ์์ ํ ์ ์๋ค. ํ๋ ค๋ฉด ์์ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค.
- ๋ง์ ์ ํผ์ฐ์ฐ์ ("Hello", "Hi")์ ๊ฒฝ์ฐ ๋ฌธ์์ด ์ฒ๋ฆฌ ํ ์ธ๋ชจ์์ด์ง๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค. ํ์ง๋ง ์คํธ๋ง์ ์์์ฌ๋ถ์ ์๊ด์์ด Java8 ์ดํ Heap์์ญ์์ ๊ด๋ฆฌ๋๋ค. ์ฆ JVM GC์ ์ผ๊ฑฐ๋ฆฌ๊ฐ ๋์ด๋๋ค.
๊ทธ๋์ ๋๊ท๋ชจ๋ก ๋ฌธ์์ด ์กฐ์์ ํ ๋์๋ StringBuilder๋ฅผ ์ฌ์ฉํด์ผ ์ฑ๋ฅ ํ๋ฝ์ด ์๋ค. ๋ ์์ธํ ๊ฑด StringBuffer์ StringBuilder๋ฅผ ๋ค๋ฃฐ ๋ ์ค๋ช ํ๋๋ก ํ๊ฒ ๋ค.
# Constant Pool ์ด๋?
๋ฐํ์์ ์์ฑ๋๋ Static ์์ ์ ์ฅ์์ด๋ค. Constant Pool ๊ฐ์ฒด์ ์ ์ฅ๋๋ฉฐ ์๋์ ๊ฐ์ ์์ ๊ฐ์ฒด๋ฅผ ๊ฐ์ง๋ค.
์ฐธ๊ณ ๋ก ์์ ํ์ Method Area, ์ฆ ์ ์ ์์ญ์ ์๋ ๋ฉ๋ชจ๋ฆฌ์ด๊ธฐ์ GC์ ๋์์ด ์๋๋ค.
// ์์ ํ์ ์ ์ฅ๋๋ ์์ ๊ฐ์ฒด
cp_info {
u1 tag; // ํ๊ทธ
u1 info[]; // ๊ฐ
}
/* tag๋ 1๋ฐ์ดํธ ์ซ์๋ก ๊ตฌ์ฑ๋๋ฉฐ JVM์๊ฒ ์๋์ ๊ฐ์ ํ์
์ ์ ๊ณตํฉ๋๋ค.
Utf8: 1
Integer: 3 (* Boolean, Short, Byte๋ ์ฌ๊ธฐ์ ํด๋น๋จ)
Float: 4
Long: 5
Double: 6
Class reference: 7
String reference: 8
*/
์ฌ๋ฏธ์๋ ์ฌ์ค์ Primarity Type ๋ฟ๋ง ์๋๋ผ String ๊ฐ์ฒด, ๋ ํผ๋ฐ์ค ํ์ ์ด ๊ฐ์ง ์ฃผ์ ๊ฐ๋ ์์ ํ๋ก ๊ด๋ฆฌ๋๋ค๋ ๊ฒ. ๋ค์๊ณผ ๊ฐ์ ์๋ฐํด๋์ค๋ฅผ ๋ง๋ค๊ณ ๋์ด์ ๋ธ๋ฌ ๋ช ๋ น์ธ javap -v ์ด๋ฆ.class ๋ฅผ ํตํด ๋ฐ์ดํธ์ฝ๋๋ฅผ ๋ถ์ํด๋ณด์.
public class ConstantPool { // class ์ด๋ฆ์ ConstantPool์ด๋ผ๊ณ ์ง์์ต๋๋ค.
public void sayHello() {
System.out.println("Hello World");
}
}
์ฐธ๊ณ ๋ก [ #n ] ์ ์์ํ์ n๋ฒ ์ธ๋ฑ์ค์ ์ ๊ทผํ๋ ๋ฐ์ดํธ์ฝ๋์ด๋ค.
[ #2 = ์์ํ์ ์์๊ฐ ]์ผ๋ก ์์ํ์ ํน์ ์ธ๋ฑ์ค์ ์์ ๊ฐ์ ๋ฑ๋ก ํ ์ ์๋ค.
// ์์์ ๋ง๋ ConstantPool.java์ ๋ฐ์ดํธ์ฝ๋.
#1 = Methodref #6.#14 // java/lang/Object."<init>":()V
#2 = Fieldref #15.#16 // java/lang/System.out:Ljava/io/PrintStream;
#3 = String #17 // Hello World
#4 = Methodref #18.#19 // java/io/PrintStream.println:(Ljava/lang/String;)V
#5 = Class #20 // com/baeldung/jvm/ConstantPool
#6 = Class #21 // java/lang/Object
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 sayHello
#12 = Utf8 SourceFile
#13 = Utf8 ConstantPool.java
#14 = NameAndType #7:#8 // "<init>":()V
#15 = Class #22 // java/lang/System
#16 = NameAndType #23:#24 // out:Ljava/io/PrintStream;
#17 = Utf8 Hello World
#18 = Class #25 // java/io/PrintStream
#19 = NameAndType #26:#27 // println:(Ljava/lang/String;)V
#20 = Utf8 com/baeldung/jvm/ConstantPool
#21 = Utf8 java/lang/Object
#22 = Utf8 java/lang/System
#23 = Utf8 out
#24 = Utf8 Ljava/io/PrintStream;
#25 = Utf8 java/io/PrintStream
#26 = Utf8 println
#27 = Utf8 (Ljava/lang/String;)V
์ข ๋ ์์ธํ๊ฒ ์ค๋ช ํ๋ฉด ์๋์ ๊ฐ๋ค.
// [UTF8 ํ์
] sayHello()๋ฉ์๋์ (์
๋ ฅ)๋ฆฌํด ํ์
์ ์์ ํ์ ์ ์ฅ. void๋ V๋ก ํ์๊ฐ๋ฅ
#8 = Utf8 ()V
// [UTF8 ํ์
] ๋ฌธ์์ด "Hello World"์ ์ฌ๋ณผ์ Hello World๋ฅผ ์ง์ ํ๊ณ ์ด๋ฅผ ์์ ํ์ ์ ์ฅ .
#17 = Utf8 Hello World
// [Class ํ์
] System.out ํด๋์ค ๋ ํผ๋ฐ์ค๋ฅผ 25๋ฒ ์์๋ก ์์ํ์ ์ ์ฅ
#18 = Class #25 // java/io/PrintStream
// [NameAndType ํ์
] .println์ Name์ 26๋ฒ์์, Type์ 27๋ฒ ์์๋ก ์ ์ฅ.
#19 = NameAndType #26:#27 // println:(Ljava/lang/String;)V
// [UTF8 ํ์
] ๋ด๊ฐ ๋ง๋ ํด๋์ค์ ์ ๊ท์ด๋ฆ์ ์ ์ฅ (fully-qualified class name)
#20 = Utf8 com/baeldung/jvm/ConstantPool
์์ํ์์ ์ ๊ณตํ๋ ํ์ ์ ์ข ๋ฅ
์์ํ์ ํ์ ์ ์ค๋ช ํ๋ ์๋ฌธ
String ์์์ ์ ํํ ๋์์ ๋ชจ๋ฅด์ง๋ง, 16๋นํธ ์์ ๋ฌธ์์ด์ ํตํด ์์ํ ๋ด๋ถ์์๋ ์ค์ ๋ฐ์ดํธ๊ฐ์ ๊ฐ๋ฅดํจ๋ค๊ณ ํฉ๋๋ค. ์๋ง ์กฐ๋ฆฝ์์ผ๋ก ์ฌ์ฉํ๋ ๋ฏ ํ๋ฐ.. ๋๋ฌด ๊น์ ๋ด์ฉ์ด๋ ๋์ค์ ๋ฐ๋ก ๊ณต๋ถํ ์์ ์
๋๋ค.
- Integer, Float: 32๋นํธ ์์ (Boolean, Short, Byte ์์๋ Integer ์ทจ๊ธ)
- Double, Long: 64๋นํธ ์์
- String: a 16-bit string constant that points at another entry in the pool which contains the actual bytes
- Class: ์ ๊ทํ๋ ํด๋์ค ์ด๋ฆ(fully qualified class name)
- Utf8: ๋ฐ์ดํธ ๋ฌธ์์ด(a stream of bytes)
- NameAndType: (์ด๋ฆ . ํ์ ) ์ผ๋ก ํ์. ๋ณดํต ๋ค๋ฅธ ์์(#13.#15)๋ฅผ ์ด์ฉํ์ฌ ์ด๋ฆ๊ณผ ํ์ ์ ์ง์
- Fieldref, Methodref, InterfaceMethodref: (Class:NameAndType) ์ผ๋ก ํ์. Class์ NameAndType์ ์์์ ์ค๋ช ํ ์์ํ์์ ์ฌ์ฉ๋๋ ํ์ ์ ์๋ฏธํจ.
# Java7 -> Java8์์์ ๋ณ๊ฒฝ์
๊ธฐ์กด์ ์๋ฐ๋ ์์ ํ์ Permanent๋ผ๋ ์ ์ ์์ญ์์ ๊ด๋ฆฌํ์์ต๋๋ค. ํ์ง๋ง Static ์์ญ์ ํ ๋น ๋ฐ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋๋ฆด์๊ฐ ์์ด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ๋ฒ๊ฑฐ๋ฌ์ ๊ณ ์์๊ฐ ์ถ๊ฐ๋๋ค๋ณด๋ฉด StackOverFlow๊ฐ ๋ฐ์ํ ์ฌ์ง๊ฐ ์์ด ๊ฒฐ๊ตญ Java8์์ Heap ์์ญ์ผ๋ก ์ ํํ๊ฒ ๋ฉ๋๋ค.
์ฐธ๊ณ ๋ก Heap์ฒ๋ผ OS Level์์ ์ ๋์ ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋น๋ฐ๋ ์์ญ์ Native Memory ๋ผ๊ณ ๋ ๋ถ๋ฆ ๋๋ค. ์ฐธ๊ณ ๋ก JVM ์ต์ ์ ์ด์ฉํ์ฌ Perm(Java7), MetaSpace(Java8)์ ๋ฉ๋ชจ๋ฆฌ ํฌ๊ธฐ๋ฅผ ์์คํ ๋ณ๋ก ํ๋ํ ์ ์์ต๋๋ค.
'๐๊ธฐ๋ณธ ์ง์ > Java ๊ธฐ๋ณธ์ง์' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
StringBuffer์ StringBulider (0) | 2021.07.27 |
---|---|
์ฐ๋ ๋ ๋๊ธฐํ (sync, volatile, AtomicClass) (0) | 2021.07.27 |
.equals์ .hashCode()๋ ํญ์ ํจ๊ป ์ค๋ฒ๋ผ์ด๋ฉํด์ผํ๋ค. (0) | 2021.07.27 |
์ ๋ค๋ฆญ(Generic)์ ๋ํ์ฌ (0) | 2021.07.26 |
์๋ฐ์์ Stack Memory & Heap Memory (0) | 2021.07.10 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
JiwonDev
JiwonDev