🌏 WEB/JAVA

λ©”λͺ¨λ¦¬ μ ˆμ•½ μŠ΅κ΄€ 듀이기 (Java Programming)

μ• μ •μ“° 2023. 4. 23. 19:44

Java 의 일반적인 문제 쀑 ν•˜λ‚˜λŠ” 높은 λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μœΌλ‘œ 인해 μ„±λŠ₯, 좩돌이 λ°œμƒν•  수 μžˆλ‹€κ³  ν•œλ‹€.

μ΅œμ ν™” 및 λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰ κ°μ†Œλ₯Ό μœ„ν•œ λͺ¨λ²• 사둀λ₯Ό μ‚΄νŽ΄λ³΄μž

 

1. Primitive type(μ›μ‹œνƒ€μž…) 을 μ‚¬μš©ν•˜μž.

μ°Έμ‘°νƒ€μž… 보닀 μ›μ‹œνƒ€μž…μ„ μ‚¬μš©ν•œλ‹€. μ›μ‹œνƒ€μž…μ„ μ‚¬μš©ν•˜λ©΄ 개체 생성 μ˜€λ²„ν—€λ“œλ₯Ό λ°©μ§€ν•˜μ—¬ λ©”λͺ¨λ¦¬λ₯Ό μ ˆμ•½ν•  수 μžˆλ‹€.

+ λ˜ν•œ μ›μ‹œνƒ€μž…μ€ μŠ€νƒ λ©”λͺ¨λ¦¬ μ—μ„œ λ°”λ‘œ 읽고, μ°Έμ‘°νƒ€μž…μ€ μŠ€νƒ λ©”λͺ¨λ¦¬μ—μ„œ νž™ λ©”λͺ¨λ¦¬μ˜ μœ„μΉ˜λ₯Ό κ΅¬ν•΄μ˜¨ λ‹€μŒμ— λ‹€μ‹œ νž™ λ©”λͺ¨λ¦¬μ— κ°€μ„œ 값을 읽어와야 ν•΄μ„œ μ„±λŠ₯상 μœ λ¦¬ν•˜λ‹€. 

 

2. λΆˆν•„μš”ν•œ 객체 생성 ν•˜μ§€λ§μž.

String s = "μ• μ •μ“°"+" μž…λ‹ˆλ‹€";

ν•΄λ‹Ή μ½”λ“œ ν•œμ€„μ€ "μ• μ •μ“° μž…λ‹ˆλ‹€" 에 λŒ€ν•œ μƒˆ λ¬Έμžμ—΄ 개체λ₯Ό λ§Œλ“­λ‹ˆλ‹€.

λŒ€μ‹  StringBuilder λ₯Ό μ‚¬μš©ν•˜μ—¬ λ¬Έμžμ—΄μ„ μΆ”κ°€ν•˜κ³  각 연결에 λŒ€ν•΄ μƒˆ 개체λ₯Ό λ§Œλ“€μ§€ μ•Šλ„λ‘ ν•œλ‹€.

StringBuilder sb = new StringBuilder();
sb.append("μ• μ •μ“°");
sb.append(" μž…λ‹ˆλ‹€");
Stirng s = sb.toString();

 

3. 지연 μ΄ˆκΈ°ν™” μ‚¬μš©

private List<String> myList;
public List<String> getMyList(){
	if(myList == null){
    	myList = new ArrayList<>();
    }
    return myList;
}

ν΄λž˜μŠ€κ°€ λ‘œλ“œλ  λ•Œ myList 개체λ₯Ό μ΄ˆκΈ°ν™”ν•˜μ§€ 말고 지연 μ΄ˆκΈ°ν™”λ₯Ό μ‚¬μš©ν•˜μ—¬ μ‹€μ œλ‘œ ν•„μš”ν•  λ•ŒκΉŒμ§€ 개체 생성을 μ—°κΈ°ν•œλ‹€.

μ΄λ ‡κ²Œ ν•˜λ©΄ λΆˆν•„μš”ν•œ 개체 생성을 λ°©μ§€ν•˜μ—¬ λ©”λͺ¨λ¦¬λ₯Ό μ ˆμ•½ν•  수 μžˆλ‹€. 

 

4. μ»¬λ ‰μ…˜ λŒ€μ‹  λ°°μ—΄ μ‚¬μš©

String[] array = new String[1000];
for (int i = 0; i< 1000; i++){
	array[i] = "Item" + i;
}

 

ArrayList λŠ” 크기가 κ°€λ³€μ μœΌλ‘œ λ³€ν•˜κΈ° λ•Œλ¬Έμ— ν‘œμ€€ λ°°μ—΄λ³΄λ‹€λŠ” λŠλ¦¬μ§€λ§Œ λ°°μ—΄μ—μ„œ λ§Žμ€ μ‘°μž‘μ΄ ν•„μš”ν•  경우 μœ μš©ν•˜κ²Œ μ‚¬μš©ν•  수 μžˆλ‹€.

ν•˜μ§€λ§Œ μ»¬λ ‰μ…˜μ˜ 크기λ₯Ό 미리 μ•Œκ³  μžˆμ„ λ•Œ κ°„λ‹¨ν•œ 배열을 μ‚¬μš©ν•˜λ©΄ 동적 크기 μ‘°μ • 및 μΆ”κ°€ λ©”μ„œλ“œμ˜ μ˜€λ²„ν—€λ“œλ₯Ό λ°©μ§€ν•˜μ—¬ λ©”λͺ¨λ¦¬λ₯Ό μ ˆμ•½ν•  수 μžˆλ‹€.

 

5. 개체 μž¬μ‚¬μš©

List<String> tempList = new ArrayList<>();
for(int i=0; i<1000; i++){
	tempList.add("ν•­λͺ© "+i);
}
tempList.clear(): // μž¬μ‚¬μš©μ„ μœ„ν•΄ λͺ©λ‘μ„ μ§€μ›λ‹ˆλ‹€.
for(int i=0; i<1000; i++){
	tempList.add("item" +i);
}

각 루프 λ°˜λ³΅μ— λŒ€ν•΄ μƒˆ ArrayListλ₯Ό μƒμ„±ν•˜λŠ” λŒ€μ‹  λ™μΌν•œ 개체λ₯Ό μ‚¬μš©ν•  λ•Œλ§ˆλ‹€ μ‚­μ œν•˜μ—¬ μž¬μ‚¬μš©ν•œλ‹€.

μ΄λ ‡κ²Œ ν•˜λ©΄ μƒμ„±λ˜λŠ” 개체 수λ₯Ό 쀄여 λ©”λͺ¨λ¦¬λ₯Ό μ ˆμ•½ν•  수 μžˆλ‹€.

 

6. 정적 νŒ©ν† λ¦¬ λ©”μ†Œλ“œ μ‚¬μš©

public static List<String> getList(){
	return new ArrayList<>(1000)
}

μƒˆ ArrayListλ₯Ό λ§Œλ“œλŠ” λŒ€μ‹  정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ§€μ •λœ 초기 용령으둜 ArrayListλ₯Ό λ§Œλ“€ 수 μžˆλ‹€.

μ΄λ ‡κ²Œ ν•˜λ©΄ μš”μ†Œλ₯Ό μΆ”κ°€ν•  λ•Œ ArrayList의 크기λ₯Ό μ‘°μ •ν•΄μ•Ό ν•˜λŠ” 횟수λ₯Ό 쀄여 λ©”λͺ¨λ¦¬λ₯Ό μ ˆμ•½ν•  수 μžˆλ‹€.

 

 

7. Flyweight μ‚¬μš©

Map<String, String> map = new HashMap<>();
String key = "myKey";
String value = "myValue";
map.put(key,value);
String anotherValue = map.get(key);

ν”ŒλΌμ΄μ›¨μ΄νŠΈ νŒ¨ν„΄μ€ 객체λ₯Ό κ³΅μœ ν•˜μ—¬ λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ„ μ€„μ΄λŠ” λ””μžμΈ νŒ¨ν„΄μž…λ‹ˆλ‹€.

μ–΄λ–€ 클래슀의 μΈμŠ€ν„΄μŠ€ ν•œ 개만 가지고 μ—¬λŸ¬ 개의 가상 μΈμŠ€ν„΄μŠ€λ₯Ό μ œκ³΅ν•˜κ³  싢을 λ•Œ μ‚¬μš©ν•œλ‹€.

private static final HashMap<String, Circle> circleMap = new HashMap<>();

public static Shape getCircle(String color) {
	Circle circle = (circle) circleMap.get(color);
    
    if(circle == null) {
    	circle = new Circle(coloer);
        circleMap.put(color,cicle);
    }
    
    return circle;
}

getCircle 둜 객체가 μžˆμ„ λ•ŒλŠ” CircleMap μ—μ„œ get ν•˜μ—¬ return ν•˜κ³  없을 λ•ŒλŠ” μƒˆλ‘œ μƒμ„±ν•œλ‹€.

 

? 이것은... 싱글톀 νŒ¨ν„΄κ³Ό μœ μ‚¬ν•˜λ‹€. λ‹€λ₯Έμ μ΄ λ¬΄μ—‡μΌκΉŒ?
μœ„μ˜ μ½”λ“œμ²˜λŸΌ Circle 은 색상이 λ°”λ€” λ•Œλ§ˆλ‹€ μƒˆλ‘œμš΄ 객체λ₯Ό μƒμ„±ν•œλ‹€. λ˜ν•œ 객체의 색상은 λ°”κΏ€ 수 μ—†λ‹€.
ν•˜μ§€λ§Œ 싱글톀 νŒ¨ν„΄μ€ 단 ν•˜λ‚˜μ˜ Circle 을 λ§Œλ“ λ‹€. λ”°λΌμ„œ λ§Œλ“€μ–΄μ§„ 단 ν•˜λ‚˜μ˜ Circle 의 색을 λ°”κΏ”μ•Ό ν•œλ‹€λŠ” λœ»μ΄λ‹€.

8. intern() 방법 μ‚¬μš©

λ¬Έμžμ—΄ λΉ„κ΅μ—λŠ” equals() ν”νžˆ μ‚¬μš©ν•œλ‹€. κ·Έλ ‡μ§€λ§Œ μ†λ„λ‚˜ λ©”λͺ¨λ¦¬ ν–₯상을 μœ„ν•΄ == μ—°μ‚°μžμ˜ μ‚¬μš©μ΄ ν•„μš”ν•  λ•Œκ°€ μžˆλ‹€.

ν•˜μ§€λ§Œ == μ—°μ‚°μžλŠ” 같은 λ©”λͺ¨λ¦¬λ₯Ό μ°Έμ‘°ν•˜λŠ”κ°€λ₯Ό λΉ„κ΅ν•˜κΈ° λ•Œλ¬Έμ— μ‹€μ œλ‘œ "A" 와 new String("A") λŠ” false κ°€ λœλ‹€.

 

그럴 λ•Œ intern() 을 μ‚¬μš©ν•œλ‹€.

intern() λ©”μ„œλ“œλŠ” String pll μ—μ„œ λ¦¬ν„°λŸ΄ λ¬Έμžμ—΄μ΄ 이미 μ‘΄μž¬ν•˜λŠ”μ§€ μ²΄ν¬ν•˜κ³  μ‘΄μž¬ν•˜λ©΄ ν•΄λ‹Ή λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•˜κ³  μ•„λ‹ˆλ©΄ λ¦¬ν„°λŸ΄μ„ String pool 에 λ„£μ–΄μ€€λ‹€.

String literal = "μ‹ μ• μ •";
String object = new String("μ‹ μ• μ •");
String intern = object.intern();

literal == object // false
literal.equlas(object) // true
literal == intern // true
literal.equals(intern) //true

 

9. λΆˆν•„μš”ν•œ μ˜€ν† λ°•μ‹± ν”Όν•˜κΈ°

int i = 10;
Integer j = Integer.valueOf(i);

AutoBoxing 은 κΈ°λ³Έ μœ ν˜•μ„ ν•΄λ‹Ή 개체 래퍼둜 μžλ™μœΌλ‘œ λ³€ν™˜ν•œλ‹€.

λΆˆν•„μš”ν•œ 개체 생성 및 λ©”λͺ¨λ¦¬ μ˜€λ²„ν•΄λ“œκ°€ λ°œμƒν•  수 있기 λ•Œλ¬Έμ—

valueOf() λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ˜€ν† λ°•μ‹±μ„ ν”Όν•˜κ³  κΈ°μ‘΄ 객체λ₯Ό μž¬μ‚¬μš© ν•œλ‹€.

 

10. finalize() λ©”μ„œλ“œλŠ” μ£Όμ˜ν•΄μ„œ μ‚¬μš©ν•˜μž

public class MyClass {
	privet byte[] data = new byte[1000];
    
    @Override
    protected void finalize() throws Throwable{
    	super.finalize();
        // λ¦¬μ†ŒμŠ€ 정리
    }
}

finalize() λ©”μ„œλ“œλŠ” κ°œμ²΄κ°€ 더 이상 μ°Έμ‘°λ˜μ§€ μ•Šμ„ λ•Œ 가비지 컬렉터에 μ˜ν•΄ ν˜ΈμΆœλ˜λŠ” Object 클래슀의 λ©”μ„œλ“œμ΄λ‹€.

κ·ΈλŸ¬λ‚˜ λ¦¬μŠ€μ†Œ 정리λ₯Ό μœ„ν•΄ finalize() λ₯Ό μ‚¬μš©ν•˜λŠ” 것은 μ˜ˆμΈ‘ν•  수 μ—†κΈ° λ•Œλ¬Έμ— λ©”λͺ¨λ¦¬ λˆ„μˆ˜λ‘œ μ΄μ–΄μ§ˆ 수 μžˆλ‹€.

 

λŒ€μ‹  try-with-resources λ₯Ό μ‚¬μš©ν•˜κ±°λ‚˜ Auto Closeable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜μ—¬ λ¦¬μ†ŒμŠ€κ°€ μ œλŒ€λ‘œ μ •λ¦¬λ˜λ„λ‘ ν•˜λŠ” 것이 μ’‹λ‹€.

try-with-resources λ₯Ό μ‚¬μš©ν•˜λ©΄ 가비지 컬렉터가 finalize() λ₯Ό ν˜ΈμΆœν•˜μ§€ μ•Šκ³ λ„ FileWriter κ°œμ²΄κ°€ μ œλŒ€λ‘œ λ‹«νžˆκ³  λ¦¬μ†ŒμŠ€κ°€ μ •λ¦¬λ˜λŠ”μ§€ 확인할 수 μžˆλ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄ 가비지 컬렉터가 μˆ˜μ§‘ν•΄μ•Ό ν•˜λŠ” 개체 수λ₯Ό 쀄여 λ©”λͺ¨λ¦¬λ₯Ό μ ˆμ•½ν•  수 μžˆλ‹€.

 

이 λͺ¨λ“  것은

λ©”λͺ¨λ¦¬ μ΅œμ ν™”κ°€ μ½”λ“œ κ°€λ…μ„±μ΄λ‚˜ μœ μ§€ 관리성을 ν¬μƒμ‹œν‚€λ©΄μ„œ 이루어지지 μ•ŠλŠ”κ²ƒμ΄ λ”μš± μ€‘μš”ν•˜λ‹€!

 

좜처
https://medium.com/javarevisited/basic-memory-saving-techniques-for-java-programming-6677a7237a69

 

λ°˜μ‘ν˜•