JAVA ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ์ฒดํฌ ๋ฐ JVM ๋ชจ๋‹ˆํ„ฐ๋ง

ํ”„๋กœ์ ํŠธ๋ฅผ ec2์— ๋ฐฐํฌํ•ด ๋’€๋Š”๋ฐ ์ž๊พธ ์„œ๋ฒ„๊ฐ€ ๋ป—๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ–ˆ๋‹ค. 

 

์ฒ˜์Œ ์ผฐ์„ ๋• ์†๋„๋„ ๋น ๋ฅด๊ณ  ๊ดœ์ฐฎ๋‹ค๊ฐ€ 2~3์‹œ๊ฐ„ ๋’ค ์ ‘์†ํ•ด๋ณด๋ฉด ๋Š๋ ค์ ธ์žˆ๊ณ  ๋‹ค์Œ ๋‚  ์ ‘์†ํ•˜๋ฉด ๋ป—์–ด์žˆ์—ˆ๋‹ค. ์ฒ˜์Œ ์ผฐ์„ ๋• ๊ดœ์ฐฎ๋‹ค๊ฐ€ ์‹œ๊ฐ„์ด ์ง€๋‚˜ ๋ป—๋Š”๊ฑธ ๋ณด์•„ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์ผ์–ด๋‚˜๋‚˜ ์‹ถ์—ˆ๋‹ค. 

 

๊ทธ๋ž˜์„œ ์ฐพ์•„๋ณด๊ฒŒ๋œ ์ž๋ฐ” ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜(memory leak)..

 

๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜(memory leak)๋ž€?

CS ์˜๋ฏธ๋กœ ์‚ดํŽด๋ณผ ๋•Œ, ์ปดํ“จํ„ฐ ํ”„๋กœ๊ทธ๋žจ์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณ„์† ์ ์œ ํ•˜๊ณ  ์žˆ๋Š” ํ˜„์ƒ์ด๋‹ค.

 

JAVA๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Garbage Collection์„ ์ง€์›ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๋“ค์ด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ์— ์˜ํ•ด ํšŒ์ˆ˜๋˜์ง€ ์•Š๊ณ  ๊ณ„์† ๋ˆ„์ ์ด ๋˜๋Š” ํ˜„์ƒ์„ ๋งํ•œ๋‹ค.

 

 

 

Java GC์˜ ํšŒ์ˆ˜ ๋Œ€์ƒ์ด ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž

 

1. ๋ฌด์˜๋ฏธํ•œ Wrapper ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ

  • GC๋Š” Immutable ๊ฐ์ฒด๋ฅผ Skipํ•œ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค๋ฉด String์€ StringBuilder์™€ ๋‹ฌ๋ฆฌ Immutable ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์— ํž™์— ๊ณ„์† ์Œ“์—ฌ์„œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ ์œ ํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค. Wrapper class์˜ ๊ฐ์ฒด๋Š” ๋ชจ๋‘ Immutable์ด๊ธฐ ๋•Œ๋ฌธ์— ์กฐ์‹ฌํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. 

2. Map์— Immutable ๋ฐ์ดํ„ฐ๋ฅผ ํ•ด์ œํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ

  • Map์—๋Š” ๊ฐ•๋ ฅํ•œ ์ฐธ์กฐ๊ฐ€ ์žˆ์–ด์„œ, ๋‚ด๋ถ€ ๊ฐ์ฒด๊ฐ€ ์‚ฌ์šฉ๋˜์ง€ ์•Š์„ ๋•Œ๋„ GC ๋Œ€์ƒ์ด ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ์ฆ‰, Map์„ ๋”์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ ์œ ํ•˜๊ณ  ์žˆ๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ์ดํ„ฐ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•˜๋‹ค.
  • WeakHashMap์€ ๋‚ด๋ถ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ดˆ๊ธฐํ™” ํ•  ์ˆ˜ ์žˆ์–ด ์ด ๊ฐ™์€ ์ƒํ™ฉ์„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.

3. Connection ์‚ฌ์šฉ ์‹œ Try Catch ์„ค๊ณ„

  •  try ๋‚ด๋ถ€์—์„œ connection์„ closeํ•˜๊ธฐ ๋•Œ๋ฌธ์—, close๊ฐ€ ์‹คํ–‰๋˜์ง€ ๋ชปํ•œ๋‹ค.
  • ๊ทธ๋ž˜์„œ Connection์ด ์—ด๋ ค์žˆ๋Š” ์ฑ„๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ ์œ ํ•˜๊ฒŒ ๋œ๋‹ค.
try {
    Connection con = DriverManager.getConnection();
    // ์˜ˆ์™ธ ํ„ฐ์ง
    con.close();
} Catch(exception e) {
	// catch
}

4. CustomKey ์‚ฌ์šฉ

๋งŒ์•ฝ Custom Key๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด equals()์™€ hashcode() ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌํ˜„ํ•ด์ค˜์•ผ ํ•œ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ Key๊ฐ’์ด ๋‹ค๋ฅธ Key๋กœ ์ธ์‹ํ•˜์—ฌ ๊ณ„์† Map์— ์Œ“์ด๊ฒŒ ๋˜๋ฉฐ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ ์œ ํ•œ๋‹ค.

 

public class CustomKey {
    private String name;
    
    public CustomKey(String name) {
        this.name=name;
    }
    
    public staticvoid main(String[] args) {
        Map<CustomKey,String> map = new HashMap<CustomKey,String>();
        map.put(new CustomKey("a"), "b");
        map.put(new CustomKey("a"), "c");
        map.put(new CustomKey("a"), "d");
   }
}

 

 

VisualVM

์‹ค์ œ๋กœ ๋‚ด ์„œ๋ฒ„์— ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ์ฒดํฌํ•˜๊ธฐ ์œ„ํ•ด VisualVM ํˆด์„ ์‚ฌ์šฉํ–ˆ๋‹ค.

 

 

  • visualVM์—์„œ remote์—ฐ๊ฒฐ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ต์…˜์„ ๋ถ™์—ฌ jarํŒŒ์ผ์„ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค.
java \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.port=8500 \
-Dcom.sun.management.jmxremote.rmi.port=8500 \
-Djava.rmi.server.hostname=192.168.56.116 \
-jar spring-example.jar

 

  • ๋‚˜๋Š” nohup์œผ๋กœ ์—ด์–ด์•ผ ํ–ˆ๊ธฐ์— ์•„๋ž˜ ๋ช…๋ น์–ด๋กœ jarํŒŒ์ผ์„ ์‹คํ–‰ํ–ˆ๋‹ค.
nohup java -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=8500 -Dcom.sun.management.jmxremote.rmi.port=8500 -Djava.rmi.server.hostname={ec2 IP} -jar -Duser.timezone=Asia/Seoul {jarํŒŒ์ผ๋ช…} >> application.log 2> deploy_err.log &

 

  • ์ด๋•Œ ec2๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ธ๋ฐ”์šด๋“œ ๊ทœ์น™์„ ์—ด์–ด์ค˜์•ผ ํ•œ๋‹ค.
  • ์œ„ ๋ช…๋ น์–ด์—์„œ 8500๋ฒˆ์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์ง€์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— 8500 port ์— ๋Œ€ํ•œ ๋ณด์•ˆ์„ ํ’€์–ด์คฌ๋‹ค.

 

 

  • visualVM์— remote๋ฅผ ์šฐํด๋ฆญ ํ›„ Add remote Host๋ฅผ ๋ˆ„๋ฅด๋ฉด ์‚ฌ์ง„๊ณผ ๊ฐ™์€ ์ฐฝ์ด ๋œฌ๋‹ค. Host name์— ec2์˜ ip๋ฅผ ์ž…๋ ฅํ•ด์ฃผ๋ฉด ์—ฐ๊ฒฐ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

 

  • ์—ฐ๊ฒฐ ํ›„ Add JMX Connection์„ ๋ˆŒ๋Ÿฌ ํ˜„์žฌ jar๋ฅผ ์‹คํ–‰์ค‘์ธ port๋ฅผ ์ž…๋ ฅํ•œ๋‹ค. ๋‚˜ ๊ฐ™์€ ๊ฒฝ์šฐ 8080์ด์—ˆ๋‹ค

 

  • Map์„ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋˜ ๊ฒŒ์‹œ๊ธ€ ์ƒ์ œ ์กฐํšŒ์— ์š”์ฒญ์„ ๋ณด๋‚ด๋ณด๊ณ  GC๊ฐ€ ์ž˜ ๋˜๋Š”์ง€ ๋ชจ๋‹ˆํ„ฐ๋ง ํ•ด๋ณด์•˜๋‹ค. ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ ํŽ˜์ด์ง€์—์„  ๊ฒŒ์‹œ๊ธ€๊ณผ 1:N์ธ ๋‹ต๋ณ€์„ ๋ถˆ๋Ÿฌ์™€์•ผํ–ˆ๊ณ , ๊ฐ ๋‹ต๋ณ€์— 1:N์ธ Comment, ReComment๊นŒ์ง€ ๋ถˆ๋Ÿฌ์™€์•ผ ํ–ˆ์–ด์„œ Map์„ ๋งŽ์ด ์‚ฌ์šฉํ–ˆ์—ˆ๋‹ค. ํž™๋คํ”„ ๊ทธ๋ž˜ํ”„๋ฅผ ๋ดค์„ ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ ๊ฐ™์ง€๋Š” ์•Š์•˜๋‹ค. 
  • ๋˜ํ•œ Heap histogram์—์„  ๊ฐ ์ž๋ฃŒํ˜• ๋งˆ๋‹ค ์‚ฌ์šฉ์ค‘์ธ ๋ฉ”๋ชจ๋ฆฌ ์–‘์„ ์•Œ ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ ๊ทธ ๋ถ€๋ถ„์—์„œ๋„ ๋”ฐ๋กœ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š” ๋ถ€๋ถ„์„ ํ™•์ธํ•˜์ง€ ๋ชป ํ–ˆ๋‹ค. 
  • ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ์ผ์–ด๋‚œ๋‹ค๋ฉด ๊ทธ๋ž˜ํ”„๊ฐ€ ๋–จ์–ด์ง€์ง€ ์•Š๊ณ  ์œ ์ง€๋˜๊ฑฐ๋‚˜ ์šฐ์ƒํ–ฅ ๋œ๋‹ค.

  • ์ถ”๊ฐ€๋กœ VisualVM์—์„œ GC๊ฐ€ ์ž˜ ๋˜๋Š”์ง€ ๋” ์ƒ์„ธํ•˜๊ฒŒ, ์ด์˜๊ฒŒ ๋ณผ ์ˆ˜ ์žˆ๋Š” plugin์ด ์žˆ๋‹ค. 
  • Visual GC ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•˜๊ณ  remoteํ™˜๊ฒฝ์— ์ถ”๊ฐ€ ์„ธํŒ…์„ ๋”ฐ๋ผํ•ด๋ด๋„ ์ž˜ ์•ˆ ๋˜์„œ ..ใ…  ์ผ๋‹จ ์—ฌ๊ธฐ๊นŒ์ง€