AST
objects that the Garbage Collector is unable to clean that causes it to get slower and slower and slower. Whenever System.gc()
is invoked, it will hang as it searches (likely) tens of thousands or hundreds of thousands of Node
references that it is unable to remove...
AST's
from The Java Heap so that the Java Garbage Collector
(a.k.a. System.gc()
) can work its magic. I don't want to call it a Java Parser Memory Leak yet - because I cannot tell whether or not the class StaticJavaParser
has a just cause in retaining the AST's
after it has parsed '.java' source files
...
AST Nodes
that are being retained in memory / on the Java Heap - permanently - are in fact being retained by the class LexicalPreservingPrinter
AND NOT by the class StaticJavaParser
? If so, how might one enforce that those AST's
are nulled (set to null
) so that they may be Garbage Collected ?
Gitter
. Hey! Danny van Bruggen if you happen to read this, I'm trying to identify whether there is a way to clear the Heap of all AST's
or Nodes
after I am done using them. My Build Script uses (quite well, actually) Java Parser to parse well over 300 source code '.java'
files - and all I can tell is that when the class Visitor
/ Handler I use "goes out of scope" for one '.java'
source code file and moves on to the next one - all of the AST Nodes
are retained in memory and cannot be garbage collected (from the last source-code file) I would just like to know if there were a way to 'null'
their references in whichever JP class
these references are being retrained.
VoidVisitorAdapter
class I use, here's The JavaDoc for it... Here are the other classes the retrieve the java.lang.String
that I need for my HTML Documentation Tool.... Here is Callable
, (JavaDoc), and 'Method' (JavaDoc), and 'Constructor' (JavaDoc), and 'Field' (JavaDoc)
public class Customer{}
won't work, but if I change it to public class Customer {}
I can add an extends no problem. The problem also goes away if I don't set the configuration of the parser to enable lexical preservation, and if I don't setup the LexicalPreservingPrinter for each Compilation Unit. If I'm not being clear I can post more details in the issues on Github, might be easier.
I have classe bellow, so I would like to have output
OUTPUT:
WebServiceXpto
method_1
call_1
call_2
String x = "end";
method_2
call_2
String x = "end";
Maybe on an map having list of method as key and list os all call stack.
CLASSE:
public class WebServiceXpto {
public void method_1() {
call_1()
}
public void method_2() {
call_2()
}
public void call_1() {
call_2()
}
public void call_2() {
String x = "end";
}
}
Hi @jlerbsc I tried but did't found solution. I din't found I way to have all children of MethodCallExpr or recursive have it
My MethodCallCheck extends VoidVisitorAdapter<Void>
public void visit(MethodCallExpr methodCallExpr, Void arg) {
super.visit(methodCallExpr, arg);
}
This is my MethodCheck extends VoidVisitorAdapter<Void>
@Override
public void visit(MethodDeclaration methodDeclaration, Void arg) {
super.visit(methodDeclaration, arg);
LOG.info("> MethodDeclaration: " + methodDeclaration.getNameAsString());
NodeList<Statement> nodeList = methodDeclaration.getBody().get().getStatements();
if (nodeList != null) {
startCheck = false;
for (Statement statement : nodeList) {
// LOG.info("> Statement: " + statement + " - " + statement.isExpressionStmt());
VoidVisitor<Void> methodCallCheck = new MethodCallCheck(packageNameBase, classNameBase, methodDeclaration.getNameAsString());
statement.accept(methodCallCheck, arg);
}
}
}
AST
after I am done with it? I have nary a clue where to start looking for that. I load AST's
by asking the class StaticJavaParser
for a CompilationUnit cu
, and then have a straightforward VoidVisitor
retrieve several String's
from the AST
... Is there any simple way to clear the AST
out of the Java Heap ("memory") after my build code moves on from one source file to the next source-file ? Would you like to help ?? (Specifically, I mean System.gc()
doesn't get the AST's
out of memory !!
Memory Analyzer
(you brought it up, before)... Umm... Do you know how in C/C++
you have to say free(ptr)
or dealloc(ptr)
(I haven't done C/C++
in 20 years)... But in Java as long as you say objReference = null
you are guaranteed that the Object objReference
(whatever it was) will be cleared from the Heap by an invokation of System.gc()
(because there are no references to it) ... How in the world can I make sure the AST
pointers that are being retained by ether LexicalPreservingPrinter
or StaticJavaParser
are set to null, so that System.gc()
will clean the heap out after my code is through with an AST
? I've got to clean that out in my build process - when the build moves from one source-file AST
and one to the next source-file AST
You quit Java Parser
... for real? Haven't you been doing this for years and years? I mean, I almost bought your book, but I'm trying not to get into the internals of the JP Code - I used it, and it (Java Parser) worked great. It gets used on hundreds of source-files every time I do a build... I just don't want to memorize the whole JP GitHub Build - I want to concentrate on my build instead... Does that make sense? (Use the API, rather than becoming a JP Developer) I know I mentioned that the JP Jar
I use is javaparser-core-3.14.159265359.jar
and I literally got it from http://jar-downloader.com
Yeah, you said the right thing, and I have tried to explain that I extract (a bunch / a lot) of java.lang.String
using a VoidVisitor
-- but after the Visitor
completes there is a bunch of stuff in memory, and I'm not keeping any references to the JavaParser
classes at all - only java.lang.String
... But OK... If you have quit this project, that's fine... It's been real.... Take care...
StringLiteralExpr a = new StringLiteralExpr("String with \"");
StringLiteralExpr b = new StringLiteralExpr().setString("String with \"");
a.b().c()
and I want to insert an extra method call in the chain to make it like a.b().d().c()
. How do I do that ? I tried using new MethodCallExpr making d
's scope be b
and c
's scope be d
but when printing I get Exception in thread "main" java.util.NoSuchElementException: No value present
at java.base/java.util.Optional.get(Optional.java:148)
at com.github.javaparser.printer.lexicalpreservation.PhantomNodeLogic.isPhantomNode(PhantomNodeLogic.java:58)
at com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter.findNodeForToken(LexicalPreservingPrinter.java:364)
at com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter.findNodeForToken(LexicalPreservingPrinter.java:375)
at com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter.findNodeForToken(LexicalPreservingPrinter.java:375)
MethodCallExpr nameMethod = cu.findAll(MethodCallExpr.class)
.stream()
.filter(mc->
mc.getNameAsString().equals("name") &&
mc.getArguments().size() == 1 &&
mc.getArgument(0).isLiteralStringValueExpr() &&
mc.getArgument(0).asLiteralStringValueExpr().getValue().equals(propertyName)
).findFirst().get();
MethodCallExpr wireClassMethod = nameMethod.findAncestor(MethodCallExpr.class, a->a.getNameAsString().equals("wireClass")).get();
MethodCallExpr wireTypeRef = new MethodCallExpr(wireClassMethod.getScope().get(), "wireTypeReference", NodeList.nodeList(new StringLiteralExpr("test")));
wireClassMethod.setScope(wireTypeRef);
PrettyPrinter
but that really messes up my code so I need to preserve the lexical structure