[
https://issues.apache.org/jira/browse/DERBY-3571?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12582649#action_12582649
]
Knut Anders Hatlen commented on DERBY-3571:
-------------------------------------------
Hi Kristian,
I think the approach sounds good. Of course, having one of the
optimizations you mentioned would be good, preferably option 2. I
think there are valid and meaningful use cases where a user doesn't
look at all the LOBs fetched, so it would be worthwhile to optimize
it. For instance, you could have code structured like this
ResultSet rs = stmt.executeQuery("select int1, int2, string1, blob1 from t");
while (rs.next()) {
...
if (someConditionIsTrue) {
processBlob(rs.getBlob(4));
}
...
}
But optimization can come later. First step is to fix the leak.
I have read through the patch. Please see my (minor) comments below.
* NetConnection:
- typo: "layber B" -> "layer B"
* Cursor:
- typo: getLocatorProedures -> getLocatorProcedures
* NoOpLOBStateTracker:
- class javadoc (and assert in noRelease()) indicates that the class
is only used when the server doesn't support locators. Isn't it
also used when the result doesn't contain LOBs?
- should we have a static instance of this class, so that we don't
have to allocate a new one each time a statement without LOBs is
executed? Since it doesn't do anything, there's no thread-safety
issues preventing us from sharing the same instance between all
the threads, I think.
* ResultSet:
- it would be good if keepLocatorColumnAlive() and
createLOBColumnTracker() had javadoc comments
+ if (this.lobState != null) {
+ if (SanityManager.DEBUG) {
+ SanityManager.THROWASSERT(
+ "LOB state tracker already initialized.");
+ }
+ }
Perhaps the above code is clearer if it's written like this?
if (SanityManager.DEBUG) {
SanityManager.ASSERT(this.lobState == null, "...");
}
+ if (type == Types.BLOB) {
+ tmpIndexes[lobCount] = i +1; // Convert to 1-based index.
+ tmpIsBlob[lobCount++] = true;
+ } else if (type == Types.CLOB) {
+ tmpIndexes[lobCount] = i +1; // Convert to 1-based index.
+ tmpIsBlob[lobCount++] = false;
+ }
Perhaps the above code could be more compact, like this?
if (type == Types.BLOB || type == Types.CLOB) {
tmpIndexes[lobCount] = i + 1; // Convert to 1-based index.
tmpIsBlob[lobCount++] = (type == Types.BLOB);
}
> LOB locators are not released if the LOB columns are not accessed by the
> client
> -------------------------------------------------------------------------------
>
> Key: DERBY-3571
> URL: https://issues.apache.org/jira/browse/DERBY-3571
> Project: Derby
> Issue Type: Bug
> Components: JDBC, Network Client
> Affects Versions: 10.3.2.1, 10.4.1.0, 10.5.0.0
> Reporter: Kristian Waagan
> Assignee: Kristian Waagan
> Attachments: derby-3571-1a-client_track_lob_fix.diff,
> derby-3571-1a-client_track_lob_fix.stat
>
>
> If the client creates a result set containing LOB locator columns and
> iterates through it without actually accessing the LOB columns, the locators
> are not released.
> The amount of locators and their associated LOB objects causes the server to
> consume large amounts of memory and it eventually gets an OOME.
> There are a few workarounds for this bug:
> a) Access and/or properly close the LOBs (i.e. Blob.free).
> This is partly dependent on DERBY-2892.
> b) Invoke Connection.commit (or rollback) periodically, which causes all
> locators on the connection to be released.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.