개요
- 자바 for loop에서 new와 StringBuilder를 사용했을 때 메모리 사용량 차이가 얼마나 날까?
위 사항에 대해 궁금해서 Runtime()을 이용해 테스트 해봤으며 테스트 조건과 코드는 다음과 같다
조건 1 : StringBuilder 사용해서 append와 delete 반복
public void builderTest(){
StringBuilder example = new StringBuilder();
for(int i = 0; i < 10000; i++){
example.append("- ");
}
String[] data = example.toString().split(" ");
int len = data.length;
Runtime run = Runtime.getRuntime();
run.gc();
StringBuilder builder = new StringBuilder();
StringJoiner joiner = new StringJoiner(" ");
long defaultMinus = run.totalMemory() - run.freeMemory();
System.out.println("builder Memory check");
for(int i =0; i < len; i++){
joiner.add(builder.append(data[i]).reverse());
builder.delete(0,data[i].length());
if((i+1) % 500 == 0) {
System.out.printf("%d번째 = #%d, total : %d,free : %d \n",
(i+1), run.totalMemory() - run.freeMemory()- defaultMinus, run.totalMemory(), run.freeMemory());
}
}
System.out.println(joiner.toString());
}
--1번째 테스트
500번째 = #55400, total : 31457280, free : 23487600
1000번째 = #55400, total : 31457280, free : 23487600
1500번째 = #165208, total : 31457280, free : 23377792
2000번째 = #165208, total : 31457280, free : 23377792
2500번째 = #165208, total : 31457280, free : 23377792
3000번째 = #266808, total : 31457280, free : 23276192
3500번째 = #266808, total : 31457280, free : 23276192
4000번째 = #266808, total : 31457280, free : 23276192
4500번째 = #299592, total : 31457280, free : 23243408
5000번째 = #401192, total : 31457280, free : 23141808
5500번째 = #401192, total : 31457280, free : 23141808
6000번째 = #401192, total : 31457280, free : 23141808
6500번째 = #502792, total : 31457280, free : 23040208
7000번째 = #502792, total : 31457280, free : 23040208
7500번째 = #502792, total : 31457280, free : 23040208
8000번째 = #502792, total : 31457280, free : 23040208
8500번째 = #669944, total : 31457280, free : 22873056
9000번째 = #669944, total : 31457280, free : 22873056
9500번째 = #669944, total : 31457280, free : 22873056
10000번째 = #669944, total : 31457280, free : 22873056
--2번째 테스트
500번째 = #55480, total : 31457280, free : 23489112
1000번째 = #55480, total : 31457280, free : 23489112
1500번째 = #151536, total : 31457280, free : 23393056
2000번째 = #151536, total : 31457280, free : 23393056
2500번째 = #247584, total : 31457280, free : 23297008
3000번째 = #247584, total : 31457280, free : 23297008
3500번째 = #247584, total : 31457280, free : 23297008
4000번째 = #247584, total : 31457280, free : 23297008
4500번째 = #343632, total : 31457280, free : 23200960
5000번째 = #343632, total : 31457280, free : 23200960
5500번째 = #439680, total : 31457280, free : 23104912
6000번째 = #439680, total : 31457280, free : 23104912
6500번째 = #439680, total : 31457280, free : 23104912
7000번째 = #439680, total : 31457280, free : 23104912
7500번째 = #535728, total : 31457280, free : 23008864
8000번째 = #535728, total : 31457280, free : 23008864
8500번째 = #601280, total : 31457280, free : 22943312
9000번째 = #697328, total : 31457280, free : 22847264
9500번째 = #697328, total : 31457280, free : 22847264
10000번째 = #697328, total : 31457280, free : 22847264
조건 2 : new 객체 생성
public void newTest(){
StringBuilder example = new StringBuilder();
for(int i = 0; i < 10000; i++){
example.append("- ");
}
String[] data = example.toString().split(" ");
int len = data.length;
Runtime run = Runtime.getRuntime();
run.gc();
StringJoiner joiner = new StringJoiner(" ");
long defaultMinus = run.totalMemory() - run.freeMemory();
System.out.println("new Memory check");
for(int i =0; i < len; i++){
joiner.add(new StringBuilder(data[i]).reverse());
if((i+1) % 500 == 0) {
System.out.printf("%d번째 = #%d, total : %d,free : %d \n",
(i+1), run.totalMemory() - run.freeMemory() -defaultMinus, run.totalMemory(), run.freeMemory());
}
}
System.out.println(joiner.toString());
}
--1번째 테스트
500번째 = #150936, total : 31457280, free : 23395160
1000번째 = #150936, total : 31457280, free : 23395160
1500번째 = #246392, total : 31457280, free : 23299704
2000번째 = #246392, total : 31457280, free : 23299704
2500번째 = #341840, total : 31457280, free : 23204256
3000번째 = #437296, total : 31457280, free : 23108800
3500번째 = #532752, total : 31457280, free : 23013344
4000번째 = #532752, total : 31457280, free : 23013344
4500번째 = #661008, total : 31457280, free : 22885088
5000번째 = #661008, total : 31457280, free : 22885088
5500번째 = #756464, total : 31457280, free : 22789632
6000번째 = #851920, total : 31457280, free : 22694176
6500번째 = #851920, total : 31457280, free : 22694176
7000번째 = #947392, total : 31457280, free : 22598704
7500번째 = #947392, total : 31457280, free : 22598704
8000번째 = #1050640, total : 31457280, free : 22495456
8500번째 = #1211664, total : 31457280, free : 22334432
9000번째 = #1211664, total : 31457280, free : 22334432
9500번째 = #1307136, total : 31457280, free : 22238960
10000번째 = #1402608, total : 31457280, free : 22143488
-- 2번째 테스트
500번째 = #55480, total : 31457280,free : 23486824
1000번째 = #151784, total : 31457280,free : 23390520
1500번째 = #248096, total : 31457280,free : 23294208
2000번째 = #248096, total : 31457280,free : 23294208
2500번째 = #344392, total : 31457280,free : 23197912
3000번째 = #440704, total : 31457280,free : 23101600
3500번째 = #440704, total : 31457280,free : 23101600
4000번째 = #537000, total : 31457280,free : 23005304
4500번째 = #666080, total : 31457280,free : 22876224
5000번째 = #666080, total : 31457280,free : 22876224
5500번째 = #762376, total : 31457280,free : 22779928
6000번째 = #858672, total : 31457280,free : 22683632
6500번째 = #858672, total : 31457280,free : 22683632
7000번째 = #952280, total : 31457280,free : 22590024
7500번째 = #952280, total : 31457280,free : 22590024
8000번째 = #1050624, total : 31457280,free : 22491680
8500번째 = #1212472, total : 31457280,free : 22329832
9000번째 = #1212472, total : 31457280,free : 22329832
9500번째 = #1308784, total : 31457280,free : 22233520
10000번째 = #1308784, total : 31457280,free : 22233520
테스트 종류 | StringBuilder | new 객체 생성 |
---|---|---|
1차 결과 | #669944, total : 31457280, free : 22873056 | #1402608, total : 31457280, free : 22143488 |
2차 결과 | #697328, total : 31457280, free : 22847264 | #1308800, total : 31457280, free : 22235392 |
결론
(#숫자) 부분이 사용된 메모리이다.
결과는 new 객체를 계속해서 생성하여 사용하는 것보다, 코드상으로 몇 자 더 적더라도 length와 StringBuilder로 append, delete 하는 것이 더 효율적으로 나왔다.
무조건 StringBuilder를 사용하는 것이 최선은 아니겠지만 서비스를 계속해서 운영하기 위해서는
메모리를 생각하지 않을 수 없기 때문에 잘 판단해서 사용하는 것이 관건이겠다.
'Software Backend > Java & Spring' 카테고리의 다른 글
자바 기초 다지기 - 4 (내부 클래스, 어노테이션, 자바) (0) | 2021.08.29 |
---|---|
javap 테스트, for문 안에서 String 문자열 합칠 경우 과연 new 객체를 생성할까? (0) | 2021.08.25 |
자바 기초 다지기 - 3 (API, Object, 추상, final, Enum, 예외, String) (0) | 2021.08.23 |
에러, error Type referred to is not an annotation type: LogExecutionTime (0) | 2021.08.22 |
자바 기초 다지기 - 2 (조건문, 반복문, 배열, 참조자료형, DTO, 상속, 오버라이딩, 오버로딩, 다형성) (0) | 2021.08.16 |