Reputation: 2843
I rented a little tomcat server to provide http-get service for an android app via jsp on dailyRazor. The maximum java heap is "Max memory: 92.81 MB".
Default tomcat setting for maxThreads was 25. As the number of users using my service growed, i was getting lots of refused connections / timeouts for the server at prime time (which i think was because the thread pool is too small). Thats why I increased the maxThreads to 250. In this night, the server crashed showing me multiple java.lang.OutOfMemoryError s. 250 seems to be a bit to heavy for the little heap :p I temporary reduced maxThreads to 50 which seems to be fine as i dont get any more errors.
As i dont know much about tomcat, i want to ask for a good way to find the right number for maxThreads. I thought about looking at the maximum memory usage of one thread. Then maxThreads = (maxMemory / memoryOfOneThread). Is there a better solution?
thanks danijoo
Upvotes: 5
Views: 5911
Reputation: 718876
The answer is that there is no good way, AFAIK. Or more precisely, nothing that is significantly better than "try it and see".
But my real reason for Answering is to point out some flaws in your understanding of your problem, and your expectations.
Threads don't use Heap memory. Or at least not directly.
The majority of a thread's memory usage is the thread stack. The thread stack size is tunable, and has a platform-specific default that can be as much as 1Mb.
However ... the thread stack is NOT allocated in the Java heap. It is allocated in off-heap memory.
If your system crashed due to an OOME when you increased the number of stacks, then the heap usage was due to the code running on the threads, not the threads themselves. (OK, you probably knew that.)
If you have a problem with requests being dropped etcetera, then increasing the number of threads is not normally the solution. In fact, it is quite likely to make throughput worse.
The thing is, that for a thread to execute it has to be assigned to a processor; i.e. a "core". Your Tomcat server may have 2 or 4 cores (I guess). So that means only 2 or 4 threads can be executing at any time. With 25 threads that meant that when all 25 are active, they get roughly 1/6th of a core's worth of CPU time. With 250 threads active (if that ever happened) they'd get 1/60th of a core. In the mean time:
Each of those requests will have created a bunch of objects, that can't be garbage collected until the request is finished.
Each of those requests could be competing for database cycles, disc I/O bandwidth, network bandwidth, and so on.
Depending on the nature of the application, there could be increased contention over data structures / database rows, resulting in increased thread context switch overheads.
There will be a sweet spot where the number of threads gives you the best request throughput. If you significantly past that, throughput (requests completed per second) will drop off, and average time to process each request will increase. Go too far and the system will grind to a halt. (OOMEs are one way this can happen. Another is requests taking so long that the clients time out and stop waiting for the responses.)
Basically, your application (when optimally tuned) will achieve a certain average throughput rate. If your actual request rate exceeds that, then the best strategy is to process the ones that you can, and drop the rest quickly. Dropping requests may seem bad, but it is better than the alternative which is taking so long to respond that the requestor times out the request and launches a new one.
Upvotes: 0
Reputation: 136022
You should add stack size in your formula. It depends on JVM, e.g. for HotSpot default stack size is about 512k per thread on 32-bit JVM. BTW with such small memory amount like you say and with 250 threads stack size may be the actual problem. Note that you can change it with -Xss
option.
Upvotes: 0
Reputation: 17435
The amount of memory used per thread depends on what you do in the thread. So it depends on your software.
It's not that easy to calculate.
But 92MB for a tomcat, that's very tight. I would look for a way to tackle that.
Upvotes: 3