문제

많은 스레드를 생성하는 루프가 있습니다.이러한 스레드에는 특히 2개의 (대규모) StringBuilder 개체가 포함되어 있습니다.그러면 이러한 스레드가 실행되어 해당 작업을 수행합니다.

그러나 일정량의 스레드 후에 이상한 충돌이 발생하는 것을 발견했습니다.이것이 StringBuilder 덕분이라는 것을 알고 있습니다. 초기 용량을 줄이면 훨씬 더 많은 스레드를 시작할 수 있기 때문입니다.이제 이러한 StringBuilder의 경우 스레드 개체의 생성자에서 다음과 같이 생성됩니다.

StringBuilder a = new StringBuilder(30000);
StringBuilder b = new StringBuilder(30000);

일반적으로 충돌이 발생하는 지점은 약 550개의 스레드이며, 그 결과 62MB가 조금 넘습니다.프로그램의 나머지 부분과 결합하면 사용 중인 메모리는 64MB일 가능성이 높습니다. 제가 온라인에서 읽은 내용은 JVM 메모리 할당 풀의 기본 크기였습니다.이것이 사실인지 아닌지는 모르겠습니다.

자, 제가 뭔가 잘못하고 있는 게 있나요? 어떻게든 디자인 때문에 메모리를 잘못된 방식으로 할당하고 있는 걸까요?아니면 이것이 유일한 방법이며 JVM에 메모리 풀을 늘리도록 지시해야 합니까?아니면 완전히 다른 것입니까?

또한 더 낮은 용량을 설정하라고 말하지 마십시오. 이러한 StringBuilder는 필요할 때 자동으로 용량을 늘리는 것을 알고 있지만 이 문제에 대한 해결책을 갖고 싶습니다.

도움이 되었습니까?

다른 팁

StringBuilder에 많은 정보를 저장하는 경우 어느 시점에서 이를 다시 참조할 예정입니까?그렇지 않다면 다른 매체(DB, ​​파일 등)에 기록하세요.프로그램에는 제한된 양의 리소스가 있으므로 전체 시스템의 모든 상태를 한 번에 보유할 수 없습니다.-Xmx는 메모리에 더 많은 저장 공간을 제공하지만 저장 능력을 무한하게 만들지는 않습니다.

사용을 고려해보세요 ThreadPoolExecutor, 을 클릭하고 풀 크기를 머신의 CPU 수로 설정하세요.CPU보다 더 많은 스레드를 생성하는 것은 단지 오버헤드를 추가하는 것입니다.

ExecutorService service = Executors.newFixedThreadPool(cpuCount))

또한 문자열을 메모리에 보관하는 대신 파일에 기록하여 메모리 사용량을 줄일 수 있습니다. StringBuilder에스.

스레드당 1MB를 가정합니다.이는 프로세스에서 할당한 메모리를 넘어서 각 항목을 생성하는 데 드는 RAM 비용입니다.

Gregory가 말했듯이 jvm에 -Xmx와 같은 몇 가지 옵션을 제공하십시오.

또한 주어진 양의 스레드만 동시에 실행되도록 하려면 ThreadPool 또는 Executor를 사용하는 것도 고려해 보세요.이렇게 하면 속도 저하 없이 메모리 양을 제한적으로 유지할 수 있습니다(어쨌든 프로세서가 동시에 550개의 스레드를 실행할 수 없기 때문입니다).

그리고 Executor를 사용하는 경우 생성자에서 StringBuilders를 생성하지 않고 run 메서드에서 생성합니다.

당신은 사용할 수 있습니다 파일라이터 텍스트를 파일로 출력한 다음 FileReader를 사용하여 다시 가져옵니다.이렇게 하면 문자열의 전체 내용이 아닌 파일 이름만 메모리에 저장하면 됩니다.

스레드를 줄이려면 ExecutorService를 사용하거나 단순히 대기열에서 읽는 몇 가지 스레드를 사용할 수 있습니다.

내 생각에는 약간만 수정하면 프로그램에 많은 메모리가 전혀 필요하지 않도록 만들 수 있을 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top