x/crypto/openpgp: newly introduced buffer has caused memory util increases #37813
Labels
FrozenDueToAge
NeedsInvestigation
Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I built my application with
x/crypto
code that includes the change introduced by https://go-review.googlesource.com/c/crypto/+/181121. This application usesx/crypto/openpgp
to encrypt very large files (ranging from GiB to TiB). Specifically https://godoc.org/golang.org/x/crypto/openpgp#SymmetricallyEncrypt.My application reads input from a network and uses
io.Copy{Buffer}()
to pass data to the encryptionio.Writer
. The[]byte
used in these operations is very large (512MiB) and we double buffer in order to both fill from the network and flush to the PGP encryption writer simultaneously.Since this change golang/crypto@32487ec added an new intermediate buffer to ensure the first write forwarded is at least 512 bytes, I've observed much greater memory util in my application.
Repro:
(Apologies is this could have been shared via the Go Playground, but I was unable to determine how to disable the garbage collector, which seems necessary to demonstrate the heap growth)
test file
What did you expect to see?
No change.
What did you see instead?
A doubling of memory util due to the
[]byte
buffer withinpartialLengthReader
being unbounded.Further investigation
It appears that
partialLengthWriter.Write()
is trying to be intelligent about the first write, with logic to avoid the buffer if the incoming[]byte
has length greater than or equal to the required 512 bytes. However, I believe this is being defeated by the setup for the symmetrically encrypted writer when it writes a single byte here. This means that the first user call toWrite()
will always see this condition evaluate true (sincelen(w.buf) == 1
) and subsequently groww.buf
to the entire size of the providedp
My humble suggestion is to provide a constant such as
maxFirstPartialWrite
which mirrors the newminFirstPartialWrite
and limits the size of the intermediate buffer.The text was updated successfully, but these errors were encountered: