Setup a small workload using virtual threads and turned on pinning detection (-Djdk.tracePinnedThreads=full), and run various methods for uploading and downloading object data.
I then reduced the pinning sights to a minimized list (grep 'monitor' run.log | grep 'com.google.cloud.storage' | sort -u)
To avoid pinning during IO operations, uses of synchronization have been replaced with ReenterantLock. There were a few synchronization sites that were also guarded by an outer operations synchronization, these too have been updated to use ReenterantLock.
We stick with synchronized for init related operations. In the case of creating a WriteChannel, the ability to open depends on the resumable session being created successfully, which requires a network request. Our objects in this area are not written in a top to bottom async friendly way to remove the synchronization at this time. Given these operations are performed at most once per WriteChannel impact is much less drastic compared to write(ByteBuffer) and close().
After this change, I ran the same workload and we are left with only the two following pins detected
Some investigation into if/how this type of pinning detection can be introduced to integration suite still needs to happen. Superficially, I'm not sure if it's practical to get JUnit4 to run everything in virtual threads, we might need to depend on some other CI external validation.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Setup a small workload using virtual threads and turned on pinning detection (-Djdk.tracePinnedThreads=full), and run various methods for uploading and downloading object data.
I then reduced the pinning sights to a minimized list (grep 'monitor' run.log | grep 'com.google.cloud.storage' | sort -u)
com.google.cloud.storage.BaseStorageReadChannel.read(BaseStorageReadChannel.java:105) <== monitors:1 com.google.cloud.storage.BlobWriteSessions$WritableByteChannelSessionAdapter.open(BlobWriteSessions.java:46) <== monitors:1 com.google.cloud.storage.LazyWriteChannel.getSession(LazyWriteChannel.java:59) <== monitors:1 com.google.cloud.storage.ParallelCompositeUploadWritableByteChannel.close(ParallelCompositeUploadWritableByteChannel.java:268) <== monitors:1 com.google.cloud.storage.ParallelCompositeUploadWritableByteChannel.write(ParallelCompositeUploadWritableByteChannel.java:178) <== monitors:1 com.google.cloud.storage.StorageByteChannels$SynchronizedBufferedWritableByteChannel.close(StorageByteChannels.java:119) <== monitors:1 com.google.cloud.storage.StorageByteChannels$SynchronizedBufferedWritableByteChannel.write(StorageByteChannels.java:109) <== monitors:1 com.google.cloud.storage.StorageByteChannels$SynchronizedUnbufferedReadableByteChannel.read(StorageByteChannels.java:139) <== monitors:1To avoid pinning during IO operations, uses of synchronization have been replaced with ReenterantLock. There were a few synchronization sites that were also guarded by an outer operations synchronization, these too have been updated to use ReenterantLock.
We stick with synchronized for init related operations. In the case of creating a WriteChannel, the ability to open depends on the resumable session being created successfully, which requires a network request. Our objects in this area are not written in a top to bottom async friendly way to remove the synchronization at this time. Given these operations are performed at most once per WriteChannel impact is much less drastic compared to write(ByteBuffer) and close().
After this change, I ran the same workload and we are left with only the two following pins detected
com.google.cloud.storage.BlobWriteSessions$WritableByteChannelSessionAdapter.open(BlobWriteSessions.java:46) <== monitors:1 com.google.cloud.storage.LazyWriteChannel.getSession(LazyWriteChannel.java:59) <== monitors:1Some investigation into if/how this type of pinning detection can be introduced to integration suite still needs to happen. Superficially, I'm not sure if it's practical to get JUnit4 to run everything in virtual threads, we might need to depend on some other CI external validation.
Part of work needed for googleapis/google-cloud-java#12641