2012-11-13 2 views
5

나는 버스트 (burst)로 로그인하고 데이터 경로를 최적화하기 위해 많은 것을 쓰고있다. 로그 텍스트는 StringBuilder으로 작성합니다. 가장 효율적인 초기 용량, 메모리 관리가 무엇이겠습니까? 그래서 JVM과 상관없이 잘 작동할까요? 목표는 재 할당을 거의 항상 피하는 것이고, 이는 약 80-100의 초기 용량으로 커버되어야합니다. 그러나 StringBuilder 인스턴스가 버퍼에서 멈추거나 쓸데없는 바이트가 자르기 때문에 가능한 한 적은 바이트를 낭비하고 싶습니다.StringBuilder의 가장 효율적인 초기 용량 크기는 무엇입니까?

나는 이것이 JVM에 달려 있다는 것을 알았지 만, 최소한의 바이트를 낭비 할 수있는 값이 있어야한다. JVM에 상관없이, "최소 공통 분모"일종의 것이다. 현재 128-16을 사용 중입니다. 128은 멋진 라운드 번호이고, 빼기는 할당 오버 헤드입니다. 또한 이것은 "조숙 한 최적화"의 사례로 간주 될 수 있지만 이후의 대답은 "엄지 손가락 기준"숫자이므로 이후에 유용 할 것임을 알고 있습니다.

나는 "나의 가장 좋은 추측"대답을 기대하지 않고있다. (내 자신의 대답은 이미 그 것이다.) 나는 누군가가 이것을 이미 연구했고 지식 기반 대답을 공유 할 수 있기를 바란다.

+0

이 질문에 대한 답변은 많은 부분에 달려 있습니다. 예를 들어 텍스트가 'StringBuilder'에 저장되는 시간 등이 있습니다. 유일한 방법은 메모리 및/또는 CPU 프로파일 러를 사용하는 측정입니다. 수십만 개의'StringBuilder' 객체를 생성하지 않는다면 몇 바이트를 걱정할 이유가 없습니다. – Jesper

+1

가장 큰 오버 헤드는 IO 비용입니다. 이 데이터를 IO에 쓰지 않으려는 경우가 아니라면 걱정하지 않으셔도됩니다. –

답변

3

글쎄, 내가 편집 한 대답을 얻기 위해, 주석 후 좀 더 테스트를 한 후 자신이 간략하게 테스트하고, 결국.

JDK 1.7.0_07 사용하고 "자바 핫스팟 (TM) 64 비트 서버 VM", StringBuilder 메모리 사용량의 단위를 VM의 이름을보고 테스트와 앱도 4 개 문자로 증가 4 개 문자이다.

Answer 의 배수는 적어도이 64 비트 JVM에서 메모리 할당 관점에서 StringBuilder와 똑같은 좋은 용량입니다.

초기 용량이 다른 1000000 StringBuilder 객체를 생성하고 다른 테스트 프로그램 실행 (초기 힙 상태가 동일) 및 전후에 ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed()을 인쇄하여 테스트합니다.

의 버퍼마다 실제 힙에서 할당 된 양은 실제로 Java char이 2 바이트이므로 예상대로 8 바이트의 짝수 배가됩니다.즉, 초기 용량이 1.00 인 1000000 개의 인스턴스를 할당하면 초기 용량이 5 ... 8 인 동일한 수의 인스턴스를 할당하는 것보다 약 8 메가 바이트 적은 메모리 (인스턴스 당 8 바이트)가 필요합니다.

+0

시험 절차를 공유 하시겠습니까? 어떻게 세분화 된 힙 사용량을 결정할 수 있습니까? – JimmyB

+0

코드를 편리하게 사용할 수는 없지만, 힙 사용량이 StringBuilder 초기 용량에서 4 단위 증가 할 때마다 한 단계 올라간 다음 3 다음 크기에 대해 거의 같았습니다. 다시 다음 4의 배수로 다시 올라갔습니다. ** 그러나 ** ** 4 바이트, 즉 8 바이트를 의미합니다. 맞습니까? 물어봐 줘서 고마워, 내일 다시 확인해 볼게. – hyde

+0

그래서 힙 사용량이 1000000 x 4 바이트 단위로 증가하는 것을 목격 했습니까? - 나는 자바 구조에서 [데이터 구조]가 차지할 자바 힙 공간의 바이트 수를 예측하는 것을 감히 생각하지 않는다. 자바 프로그램에서는 char과 다른 값/유형이 아니다. 게다가 힙의 할당 * 세분성에 관계없이 GC가 메모리를 힙으로 다시 릴리스하기로 결정할 때의 세분성은 알려지지 않았으며 모든 측정에 영향을 미칩니다. - 당신이 호기심에서 테스트를하고 있거나 주어진 JVM의 특성을 측정하고 있다면, 진행하십시오. - 그렇지 않으면, ... 위의 내 대답을 참조하십시오. – JimmyB

4

이 경우 똑똑하지 마십시오.

현재 128-16을 사용하고 있는데, 128은 멋진 라운드 번호이고, 뺄셈은 할당 오버 헤드입니다.

Java의 경우 이것은 JVM의 내부 작동에 대한 전적으로 임의의 가정을 기반으로합니다. Java는 C가 아닙니다. 바이트 정렬 등은 이 아니며은 프로그래머가 악용 할 수 있거나 시도해야하는 문제입니다.

문자열의 최대 길이를 알고있는 경우이를 초기 크기로 사용할 수 있습니다. 그 외에도 최적화 시도는 간단합니다.

당신이 정말 StringBuilder의 방대한 양의 당신이 정말 JVM을 설득 할 필요를 느끼지 매우 오랜 기간 동안 주위 (아주 로깅의 개념에 맞지 않는), 및 것를 알고있는 경우 힙 공간의 일부 바이트를 저장하려면 문자열을 완전히 작성한 후 trimToSize()을 사용해보십시오. 그러나 문자열이 메가 바이트를 낭비하지 않는 한, 응용 프로그램의 다른 문제에 집중해야합니다.

관련 문제