Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak(?) in Version 1.0.24 #32

Open
viktor-ch opened this issue Dec 27, 2018 · 2 comments
Open

Memory leak(?) in Version 1.0.24 #32

viktor-ch opened this issue Dec 27, 2018 · 2 comments

Comments

@viktor-ch
Copy link

It seems to be a memory leak in the latest version when calling .exec() within a promise.

I tested two last versions (1.0.23 and 1.0.24) with node 10.14.2 using the test code below. The standard callback approach works just fine in both versions. But when using promises I observed significant heap usage growth in version 1.0.24.

Thank you very much in advance,
Viktor

Test results:

v.1.0.23:
Callbacks:
Start : heapTotal = 6.23 MB, heapUsed = 3.73 MB
Finish: heapTotal = 40.23 MB, heapUsed = 9.94 MB
Promises:
Start : heapTotal = 6.23 MB, heapUsed = 3.73 MB
Finish: heapTotal = 43.23 MB, heapUsed = 19.33 MB

v.1.0.24:
Callbacks:
Start : heapTotal = 6.23 MB, heapUsed = 3.73 MB
Finish: heapTotal = 43.23 MB, heapUsed = 9.95 MB
Promises:
Start : heapTotal = 6.23 MB, heapUsed = 3.73 MB
Finish: heapTotal = 617.23 MB, heapUsed = 578.01 MB

Test :

const conn = require('sqlanywhere').createConnection();

const dbParams = {
    // Server  : 'xxxxx',
    UserId  : 'DBA',
    Password: 'sql',
  };
const select = "SELECT row_num, 'test long long string' || row_num as str FROM sa_rowgenerator( 1, 50000 );"

//----------------------------------------------------------------------
// execute the select 'count' times using the standard callback approach 
function testCallback(count) {
    const exec = function() {
        conn.exec(select, (err, result) => {
            if(err) {
                console.log(err);
            }
            else {
                console.log(`Iteration: ${count} Rows: ${result.length}`);
                if(--count > 0) {
                    setTimeout(exec, 0)
                }
                else {
                    conn.disconnect(err => logMemoryUsage(usedStart, process.memoryUsage()));
                }
            }
        })
    }
    conn.connect(dbParams, err => err ? console.log(err) :  exec());
 }

//----------------------------------------------------------------------
// execute the select 'count' times using Promises 
async function testPromise(count) {
    const connect = async function() {
        return new Promise( (resolve, reject) => {
            conn.connect(dbParams, err => err ? reject(err) : resolve());
        });
    }
    const disconnect = async function() {
        return new Promise( (resolve, reject) => {
            conn.disconnect(err => err ? reject(err) : resolve());
        });
    }
    const exec = async function() {
        return new Promise( (resolve, reject) => {
            conn.exec(select, (err, result) => err ? reject(err) : resolve(result));
        });
    }
    try {
        await connect();
        for(let i = count; i > 0; --i) {
            const result = await exec();
            console.log(`Iteration: ${i} Rows: ${result.length}`);
        }
        await disconnect();
        logMemoryUsage(usedStart, process.memoryUsage());
    }
    catch(err) {
        console.log(err);
    }
 }

//----------------------------------------------------------------------
const usedStart = process.memoryUsage();
function logMemoryUsage(startMemory, finishMemory) {
    const toMB = mem => Math.round(mem / 1024 / 1024 * 100) / 100; 
    console.log(`Start : heapTotal = ${toMB(startMemory.heapTotal) } MB, heapUsed = ${toMB(startMemory.heapUsed) } MB`);
    console.log(`Finish: heapTotal = ${toMB(finishMemory.heapTotal)} MB, heapUsed = ${toMB(finishMemory.heapUsed)} MB`);
}

//----------------------------------------------------------------------
// enable one of the following functions:
//----------------------------------------------------------------------
// testCallback(100);
testPromise(100);
@steveostop
Copy link

I can confirm having memory leak issues as well using the most recent version. I have a simple ExpressJS API setup to retrieve data for an internal webapp.

Using async/await the app quickly grows in memory usage crashes.

Just now refactored to not use async/await and the app's heap usage never gets close in comparison.

@Megapixel99
Copy link

Has this been fixed?

Megapixel99 referenced this issue in Megapixel99/sqlanywhere-knex Jan 19, 2024
Megapixel99 referenced this issue in Megapixel99/sqlanywhere-knex Jan 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants