This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 168423 - Would like some more useful OQL queries for heap dumps.
Summary: Would like some more useful OQL queries for heap dumps.
Status: NEW
Alias: None
Product: profiler
Classification: Unclassified
Component: Base (show other bugs)
Version: 6.x
Hardware: All All
: P3 blocker (vote)
Assignee: issues@profiler
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-07-10 23:24 UTC by i30817
Modified: 2009-09-07 02:06 UTC (History)
0 users

See Also:
Issue Type: ENHANCEMENT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description i30817 2009-07-10 23:24:57 UTC
Especially i thought of a query of duplicated chains with more than one BufferedReader or BufferedWriter or
BufferedInputStream or BufferedOutputStream. These are performance limitations that are hard to detect.

Don't have a clue how to write the query, but this is my suggestion anyway.
Comment 1 i30817 2009-07-10 23:28:09 UTC
When i wroted duplicated chains i meant of course, the insertion of a BufferedXXX on a stream that already passed
through a BufferedXXX (same input/output kind).

Now that i think about it PipedInput/Output stream are also candidates since they buffer streams too. 
Comment 2 i30817 2009-09-06 19:28:08 UTC
I'm not sure this is exactly right, since i copied this from from the overallocated string example, and i didn't know
the purpose of the top function, and the logic is more complex so this probably has duplicated results, if it works at
all (didn't test it yet). But it's enough to get an idea:

[code]
var duplicated;

function overAllocationFilterInputStream(it) {
    try { 
    while(it instanceof java.io.FilterInputStream){
        var stream = it["in"];
        if(stream instanceof java.io.BufferedInputStream ||
            stream instanceof java.io.ByteArrayInputStream ||
            stream instanceof java.io.StringBufferInputStream ||
            stream instanceof java.io.PipedInputStream){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    }catch (e) {println("Shouldn't happen");}
    return false;
}
function overAllocationFilterOutputStream(it) {
    try { 
    while(it instanceof java.io.FilterOutputStream){
        var stream = it["out"];
        if(stream instanceof java.io.BufferedOutputStream ||
            stream instanceof java.io.ByteArrayOutputStream ||
            stream instanceof java.io.PipedOutputStream){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    }catch (e) {println("Shouldn't happen");}
    return false;
}

function overAllocationReader(it) {
    try { 
    while(it instanceof java.io.BufferedReader ||
            it instanceof java.io.FilterReader){
        var stream = it["in"];
        if(stream instanceof java.io.BufferedReader ||
            stream instanceof java.io.PipedReader ||
            stream instanceof java.io.CharArrayReader ||
            stream instanceof java.io.StringReader){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    }catch (e) {println("Shouldn't happen");}
    return false;
}

function overAllocationWriter(it) {
    try { 
    while(it instanceof java.io.BufferedWriter ||
            it instanceof java.io.FilterWriter){
        var stream = it["out"];
        if(stream instanceof java.io.BufferedWriter ||
            stream instanceof java.io.PipedWriter ||
            stream instanceof java.io.CharArrayWriter ||
            stream instanceof java.io.StringWriter){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    }catch (e) {println("Shouldn't happen");}
    return false;
}

function showOAinfo(it) {
    return toHtml(it) + " buffers data that " + toHtml(duplicated) + " also does, one of them probably should be
eliminated.";
}

//these must buffer data AND be in a chain
map(heap.objects("java.util.zip.InflaterInputStream", false, 'overAllocationFilterInputStream(it)'), showOAinfo);
map(heap.objects("java.io.BufferedInputStream", false, 'overAllocationFilterInputStream(it)'), showOAinfo);
map(heap.objects("java.util.zip.DeflaterOutputStream", false, 'overAllocationFilterOutputStream(it)'), showOAinfo);
map(heap.objects("java.io.BufferedOutputStream", false, 'overAllocationFilterOutputStream(it)'), showOAinfo);
map(heap.objects("java.io.BufferedReader", false, 'overAllocationReader(it)'), showOAinfo);
map(heap.objects("java.io.BufferedWriter", false, 'overAllocationReader(it)'), showOAinfo);
[/code]

Name :
Overallocated buffer stream/reader

Description : 
Finds buffered streams/readers from the jdk that are overallocated, and thus only move data from one memory zone to
another. False positives can happen with two functional streams/readers that happen to buffer, like InflaterInputStream
and PipedInputStream.
Comment 3 i30817 2009-09-06 22:48:14 UTC
Ok i think i did it, modulo all the nitpicks above. I wasn't expecting that instanceof doesn't work as expected.

[code]
var duplicated;

function overAllocationFilterInputStream(it) {
    while('it instanceof java.io.FilterInputStream'){
        var stream = it["in"];
        if('stream instanceof java.io.BufferedInputStream ||'+
           'stream instanceof java.io.ByteArrayInputStream ||'+
           'stream instanceof java.io.StringBufferInputStream ||'+
           'stream instanceof java.io.PipedInputStream'){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function overAllocationFilterOutputStream(it) {
    while('it instanceof java.io.FilterOutputStream'){
        var stream = it["out"];
        if('stream instanceof java.io.BufferedOutputStream ||'+
           'stream instanceof java.io.ByteArrayOutputStream ||'+
           'stream instanceof java.io.PipedOutputStream'){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function overAllocationReader(it) {
    while('it instanceof java.io.BufferedReader || it instanceof java.io.FilterReader'){
        var stream = it["in"];
        if('stream instanceof java.io.BufferedReader ||'+
           'stream instanceof java.io.PipedReader ||'+
           'stream instanceof java.io.CharArrayReader ||'+
           'stream instanceof java.io.StringReader'){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function overAllocationWriter(it) {
    while('it instanceof java.io.BufferedWriter || it instanceof java.io.FilterWriter'){
        var stream = it["out"];
        if('stream instanceof java.io.BufferedWriter ||'+
           'stream instanceof java.io.PipedWriter ||'+
           'stream instanceof java.io.CharArrayWriter ||'+
           'stream instanceof java.io.StringWriter'){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function showOAinfo(it) {
    return toHtml(it) + " buffers data that " + toHtml(duplicated) + " also does, one of them probably should be
eliminated.";
}

map(
concat(
concat(
concat(
concat(
concat(
heap.objects("java.util.zip.InflaterInputStream", false, 'overAllocationFilterInputStream(it)'),
heap.objects("java.io.BufferedInputStream", false, 'overAllocationFilterInputStream(it)')), 
heap.objects("java.util.zip.DeflaterOutputStream", false, 'overAllocationFilterOutputStream(it)')),
heap.objects("java.io.BufferedOutputStream", false, 'overAllocationFilterOutputStream(it)')),
heap.objects("java.io.BufferedReader", false, 'overAllocationReader(it)')),
heap.objects("java.io.BufferedWriter", false, 'overAllocationWriter(it)')), showOAinfo);
[/code]

Name :
Overallocated buffer stream/reader

Description : 
Finds buffered streams/readers from the jdk that are overallocated, and thus only move data from one memory zone to
another. False positives can happen with two functional streams/readers that happen to buffer, like InflaterInputStream
and PipedInputStream.
Comment 4 i30817 2009-09-06 23:34:25 UTC
Actually this still doesn't work, putting a string instead of instanceof is just making the condition evaluate to
true... Using instanceof doesn't work, i assume since it's reserved for the OQL queries..
Comment 5 i30817 2009-09-07 00:03:46 UTC
Ok, this should do it:

var duplicated;

function instanceOf(it, other){
    var c2 = heap.findClass(other);
    if(c2 == null)
        return false;
    var c1 = classof(it);
    try{
    return c1.name.equals(c2.name) || c1.isSubclassOf(c2);
    }catch(e){return false;}
}

function overAllocationFilterInputStream(it) {
    while(instanceOf(it, "java.io.FilterInputStream")){
        var stream = it["in"];
        if(instanceOf(stream, "java.io.BufferedInputStream") ||
           instanceOf(stream, "java.io.ByteArrayInputStream") ||
           instanceOf(stream, "java.io.StringBufferInputStream") ||
           instanceOf(stream, "java.io.PipedInputStream")){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function overAllocationFilterOutputStream(it) {
    while(instanceOf(it, "java.io.FilterOutputStream")){
        var stream = it["out"];
        if(instanceOf(stream,  "java.io.BufferedOutputStream") ||
           instanceOf(stream,  "java.io.ByteArrayOutputStream") ||
           instanceOf(stream, "java.io.PipedOutputStream")){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function overAllocationReader(it) {
    while(instanceOf(it, "java.io.BufferedReader") || instanceOf(it, "java.io.FilterReader")){
        var stream = it["in"];
        if(instanceOf(stream, "java.io.BufferedReader") ||
           instanceOf(stream, "java.io.PipedReader") ||
           instanceOf(stream, "java.io.CharArrayReader") ||
           instanceOf(stream, "java.io.StringReader")){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function overAllocationWriter(it) {
    while(instanceOf(it, "java.io.BufferedWriter") || instanceOf(it, "java.io.FilterWriter")){
        var stream = it["out"];
        if(instanceOf(stream, "java.io.BufferedWriter") ||
           instanceOf(stream, "java.io.PipedWriter") ||
           instanceOf(stream, "java.io.CharArrayWriter") ||
           instanceOf(stream, "java.io.StringWriter")){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function showOAinfo(it) {
    return toHtml(it) + " buffers data that " + toHtml(duplicated) + " also does, one of them probably should be
eliminated.";
}

map(
concat(
concat(
concat(
concat(
concat(
heap.objects("java.util.zip.InflaterInputStream", false, 'overAllocationFilterInputStream(it)'),
heap.objects("java.io.BufferedInputStream", false, 'overAllocationFilterInputStream(it)')), 
heap.objects("java.util.zip.DeflaterOutputStream", false, 'overAllocationFilterOutputStream(it)')),
heap.objects("java.io.BufferedOutputStream", false, 'overAllocationFilterOutputStream(it)')),
heap.objects("java.io.BufferedReader", false, 'overAllocationReader(it)')),
heap.objects("java.io.BufferedWriter", false, 'overAllocationWriter(it)')), showOAinfo);
Comment 6 i30817 2009-09-07 02:06:25 UTC
This one is better. But i finally understood why the heap walker is not a good tool for this kind of optimization. Since
it only captures a snapshot it never can show all instances of this kind of ineficiency, since its likely the snapshot
is at the wrong time. Any way to take automatic mini dumps, say, on every constructor of a class, or before a class is
GC'd? 

var duplicated;

function instanceOf(it, other){
    c2 = heap.findClass(other);
    if(c2 == null)
        return false;
    c1 = classof(it);
    return c1 == c2 || c1.isSubclassOf(c2);
}

function overAllocationFilterInputStream(it) {
    while(instanceOf(it, "java.io.FilterInputStream")){
        stream = it["in"];
        if(instanceOf(stream, "java.io.BufferedInputStream") ||
           instanceOf(stream, "java.io.ByteArrayInputStream") ||
           instanceOf(stream, "java.io.StringBufferInputStream") ||
           instanceOf(stream, "java.io.PipedInputStream")){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function overAllocationFilterOutputStream(it) {
    while(instanceOf(it, "java.io.FilterOutputStream")){
        stream = it["out"];
        if(instanceOf(stream,  "java.io.BufferedOutputStream") ||
           instanceOf(stream,  "java.io.ByteArrayOutputStream") ||
           instanceOf(stream, "java.io.PipedOutputStream")){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function overAllocationReader(it) {
    while(instanceOf(it, "java.io.BufferedReader") || instanceOf(it, "java.io.FilterReader")){
        stream = it["in"];
        if(instanceOf(stream, "java.io.BufferedReader") ||
           instanceOf(stream, "java.io.PipedReader") ||
           instanceOf(stream, "java.io.CharArrayReader") ||
           instanceOf(stream, "java.io.StringReader")){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function overAllocationWriter(it) {
    while(instanceOf(it, "java.io.BufferedWriter") || instanceOf(it, "java.io.FilterWriter")){
        stream = it["out"];
        if(instanceOf(stream, "java.io.BufferedWriter") ||
           instanceOf(stream, "java.io.PipedWriter") ||
           instanceOf(stream, "java.io.CharArrayWriter") ||
           instanceOf(stream, "java.io.StringWriter")){
            duplicated = stream;
            return true;
          }
        it = stream;
    }
    return false;
}

function showOAinfo(it) {
    return toHtml(it) + " buffers data that " + toHtml(duplicated) + " also does, one of them probably should be
eliminated.";
}

map(
concat(
concat(
concat(
concat(
concat(
heap.objects("java.util.zip.InflaterInputStream", false, 'overAllocationFilterInputStream(it)'),
heap.objects("java.io.BufferedInputStream", false, 'overAllocationFilterInputStream(it)')), 
heap.objects("java.util.zip.DeflaterOutputStream", false, 'overAllocationFilterOutputStream(it)')),
heap.objects("java.io.BufferedOutputStream", false, 'overAllocationFilterOutputStream(it)')),
heap.objects("java.io.BufferedReader", false, 'overAllocationReader(it)')),
heap.objects("java.io.BufferedWriter", false, 'overAllocationWriter(it)')), showOAinfo);