-
Notifications
You must be signed in to change notification settings - Fork 137
Description
Describe the bug?
A memory leak was introduced in ApiClient.java in these two lines:
| private Map<Long, Integer> lastStatusCodeByThread = new ConcurrentHashMap<>(); |
| private Map<Long, Map<String, List<String>>> lastResponseHeadersByThread = new ConcurrentHashMap<>(); |
These concurrent maps reinvent the wheel of a thread local variable in java - https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadLocal.html
But it's a poor implementation, as it never gets cleaned up as threads end. This means as Threads are spawned and killed in a long running java application, these maps will get larger and larger and never free up their memory.
A trivial improvement is to instead use ThreadLocal. That will at least bound this memory leak to active threads that have used the api client, as ThreadLocal cleans up after itself.
Alternatively, a much cleaner method of pagination is found in the AWS Java S3 client:
https://docs.aws.amazon.com/AmazonS3/latest/API/s3_example_s3_ListObjectsV2_section.html
A good pagination implementation shouldn't require a clumsy loop in every client that connects to Okta..
What is expected to happen?
No memory leak in long running java processes, and no attempts to reinvent ThreadLocal variables.
What is the actual behavior?
Memory leaks as threads are created and killed
Reproduction Steps?
Create a java process, create a new thread, run an api request in that thread, exit, rinse and repeat. And watch the sdk eat your memory.
Additional Information?
No response
Java Version
Any java version.
SDK Version
23.0.1
OS version
Doesn't matter.