[ 
https://issues.apache.org/jira/browse/DERBY-7049?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16891853#comment-16891853
 ] 

Rick Hillegas commented on DERBY-7049:
--------------------------------------

Here is a way to discover how many unique statements your program is generating.

Attaching StatementLogReadingVTI.java. This is a table function which reads 
derby.log and finds all of the statements which have been compiled--provided 
that the engine was booted with the following trace flags:

{noformat}
-Dderby.language.logStatementText=true
-Dderby.stream.error.logSeverityLevel=0
{noformat}

1) Compile StatementLogReadingVTI and put it on your classpath.

2) Then run the following script. You will need to substitute your own 
derby.log for the one mentioned in the script.

3) The final query should print out the number of unique statements produced by 
your program.

{noformat}
connect 'jdbc:derby:memory:db;create=true';

CREATE FUNCTION readStatements
(
  fileName VARCHAR(32672),
  charSet VARCHAR(100)
)
RETURNS TABLE
(
  statement_text VARCHAR(32672)
)
LANGUAGE JAVA
PARAMETER STYLE DERBY_JDBC_RESULT_SET
NO SQL
EXTERNAL NAME 'StatementLogReadingVTI.readStatements'
;

CREATE TABLE statementText(statement_text VARCHAR(32672));

INSERT INTO statementText
  SELECT * FROM TABLE
  (
    readStatements('/Users/rhillegas/derby/mainline/derby.log1', 'UTF-8')
  ) t
;

SELECT COUNT (DISTINCT statement_text) FROM statementText;
{noformat}


> OutOfMemoryError: Compressed class space
> ----------------------------------------
>
>                 Key: DERBY-7049
>                 URL: https://issues.apache.org/jira/browse/DERBY-7049
>             Project: Derby
>          Issue Type: Bug
>          Components: SQL
>    Affects Versions: 10.13.1.1
>            Reporter: Marco
>            Priority: Major
>         Attachments: StatementLogReadingVTI.java
>
>
> After a few days of working with an embedded Derby database (currently 
> version 10.13.1.1 on Oracle Java 1.8.0_201-b09), the following error occurs:
> *java.lang.OutOfMemoryError: Compressed class space*
> {code:java}
> java.lang.OutOfMemoryError: Compressed class space
>     at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.8.0_201]
>     at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[na:1.8.0_201]
>     at java.lang.ClassLoader.defineClass(ClassLoader.java:642) ~[na:1.8.0_201]
>     at 
> org.apache.derby.impl.services.reflect.ReflectLoaderJava2.loadGeneratedClass(Unknown
>  Source) ~[derby-10.13.1.1.jar:na]
>     at 
> org.apache.derby.impl.services.reflect.ReflectClassesJava2.loadGeneratedClassFromData(Unknown
>  Source) ~[derby-10.13.1.1.jar:na]
>     at 
> org.apache.derby.impl.services.reflect.DatabaseClasses.loadGeneratedClass(Unknown
>  Source) ~[derby-10.13.1.1.jar:na]
>     at 
> org.apache.derby.impl.services.bytecode.GClass.getGeneratedClass(Unknown 
> Source) ~[derby-10.13.1.1.jar:na]
>     at 
> org.apache.derby.impl.sql.compile.ExpressionClassBuilder.getGeneratedClass(Unknown
>  Source) ~[derby-10.13.1.1.jar:na]
>     at org.apache.derby.impl.sql.compile.StatementNode.generate(Unknown 
> Source) ~[derby-10.13.1.1.jar:na]
>     at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source) 
> ~[derby-10.13.1.1.jar:na]
>     at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source) 
> ~[derby-10.13.1.1.jar:na]
>     at 
> org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(Unknown
>  Source) ~[derby-10.13.1.1.jar:na]
>     at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown 
> Source) ~[derby-10.13.1.1.jar:na]
>     at org.apache.derby.impl.jdbc.EmbedPreparedStatement42.<init>(Unknown 
> Source) ~[derby-10.13.1.1.jar:na]
>     at org.apache.derby.jdbc.Driver42.newEmbedPreparedStatement(Unknown 
> Source) ~[derby-10.13.1.1.jar:na]
>     at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown 
> Source) ~[derby-10.13.1.1.jar:na]
>     at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown 
> Source) ~[derby-10.13.1.1.jar:na]
>     at 
> org.datanucleus.store.rdbms.datasource.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:259)
>  ~[datanucleus-rdbms-4.0.12.jar:na]{code}
> I tried to solve the problem by periodically shutting down the database, 
> because I read that the generated classes as well as all other allocated 
> resources should be released when the DB is shut-down.
> I thus perform the following code once per roughly 20 minutes:
> {code:java}
> String shutdownConnectionURL = connectionURL + ";shutdown=true";
> try {
>     DriverManager.getConnection(shutdownConnectionURL);
> } catch (SQLException e) {
>     int errorCode = e.getErrorCode();
>     if (DERBY_ERROR_CODE_SHUTDOWN_DATABASE_SUCCESSFULLY != errorCode &&
>             DERBY_ERROR_CODE_SHUTDOWN_DATABASE_WAS_NOT_RUNNING != errorCode) {
>         throw new RuntimeException(e);
>     }
> }
> {code}
> Unfortunately, this has no effect :( The OutOfMemoryError still occurs after 
> about 2 days. Do I assume correctly that the above code _should_ properly 
> shut-down the database? And do I assume correctly that this shut-down should 
> release the generated classes?
> IMHO, it is already a bug in Derby that I need to shut-down the database at 
> all in order to prevent it from piling up generated classes. Shouldn't it 
> already release the generated classes at the end of each transaction? But 
> even if I really have to shut-down the DB, it is certainly a bug that the 
> classes are still kept in "compressed class space" even after the shut-down.
> I searched the release notes and the existing bugs (here in JIRA) and did not 
> find anything related to this {{OutOfMemoryError}}. Hence, I open this 
> bug-report, now.
> This issue was originally reported in 
> [subshare#74|https://github.com/subshare/subshare/issues/74], but it is IMHO 
> clearly a Derby bug.



--
This message was sent by Atlassian JIRA
(v7.6.14#76016)

Reply via email to