I have created a Java program which reads encrypted files from local system and does some processing. Actually I have 20 files to read so I have used threading mechanism to speed up the program execution.
When I run the program in Eclipse it takes more than 30 minutes to complete the execution, whereas if I make a runnable jar and execute the program using command prompt, it takes less than a minute.
Why does running programs in Eclipse take more time than running them in command prompt?
Eclipse's Console view that captures System.out is notoriously slow compared to the regular stdout of the command line. Whenever there is a lot of printing happening in the program, it is to be expected that the program will run significantly slower from Eclipse.
But anyway, unless you are writing a program designed to integrate with other programs via Unix pipes, you should minimize the printing as it will kill performance even at the command line.
There are some typical mistakes:
Maybe you are executing your program in Debug mode.
Try to use Run (play symbol inside a green circle) instead of Debug (a green bug)
Maybe you are executing your program with a different JVM
Take a look in Project Properties->Java compiler, Window->Preferences->Java->Compiler and Window->Preferences->Java->Installed JREs
The output and input interactions with Java Console of Eclipse JDT differ on performance than standard console.
Ensure that you use the Run action in Eclipse, and not Debug, as the latter really has measurable difference, especially if you use conditional breakpoints.
However, I remember having less significant differences arising from the use of the Debug.
I have just did an experiment for you and did not saw so significant difference.
I created class that calculates sin() 100000000 times.
This program ran ~15 seconds under eclipse and ~14 seconds via command prompt.
So, here are the reasons for slowness in your system I can see at the top of my head:
Be sure that you are not running under debug. Use Run option, not Debug.
Be sure that you do not have some coverage/monitoring developers tools on under eclipse. For example YourKit, Emma etc.
Be sure that your program does not produce significant prints to the console.
Check that you have enough heap memory when running under eclipse
Changing jdk 6 to jdk 7 worked perfectly for me.
Window->Preferences->Java->Installed JREs
Related
I have an obfuscated Java 8 program and I want to attach a Java agent to it. But when I start it with java -javaagent:intrace-agent.jar -jar program.jar it launches and disattaches from the console after a few seconds, my agent finishes. If I try to see program's command line args in Process Explorer, there's a -XX:+DisableAttachMechanism option (this program adds it during startup somehow). Are there any ways to bypass that?
Thanks in advance!
There's two approaches you can take to get around that:
Modify the program's bytecode to make it not relaunch itself like that.
Get the OpenJDK source, remove the check that makes that option do anything, and then run the program in that environment.
Note that with either of those approaches, the program might end up noticing that you did it and doing something else to foil you.
I have a Java application that needs to run several times. Every time it runs, it checks if there's data to process and if so, it processes the data.
I'm trying to figure out what's the best approach (performance, resource consumption, etc.) to do this:
1.- Launch it once, and if there's nothing to process make it sleep (All Java).
2.- Using a bash script to launch the Java app, and when it finishes, sleep (the script) and then relaunch the java app.
I was wondering if it is best to keep the Java app alive (sleeping) or relaunching every time.
It's hard to answer your question without the specific context. On the face of it, your questions sounds like it could be a premature optimization.
Generally, I suggest you do what's easier for you to do (and to maintain), unless you have good reasons not to. Here are some possible good reasons, pick the ones appropriate to your situation:
For sleeping in Java:
The check of whether there's new data is easier in Java
Starting the Java program takes time or other resources, for example if on startup, your program needs to load a bunch of data
Starting the Java process from bash is complex for some reason - maybe it requires you to fiddle with a bunch of environment variables, files or something else.
For re-launching the Java program from bash:
The check of whether there's new data is easier in bash
Getting the Java process to sleep is complex - maybe your Java process is a complex multi-threaded beast, and stopping, and then re-starting the various threads is complicated.
You need the memory in between Java jobs - killing the Java process entirely would free all of its memory.
I would not keep it alive.
Instead of it you can use some Job which runs at defined intervals you can use jenkins or you can use Windows scheduler and configure it to run every 5 minutes (as you wish).
Run a batch file with Windows task scheduler
And from your batch file you can do following:
javac JavaFileName.java // To Compile
java JavaFileName // to execute file
See here how to execute java file from cmd :
How do I run a Java program from the command line on Windows?
I personally would determine it, by the place where the application is working.
if it would be my personal computer, I would use second option with bash script (as resources on my local machine might change a lot, due to extensive use of some other programs and it can happen that at some point I might be running out of memory for example)
if it goes to cloud (amazon, google, whatever) I know exactly what kind of processes are running there (it should not change so dynamically comparing to my local PC) and long running java with some scheduler would be fine for me
I did some simple function call and string operation in a loop, the java program runs much faster under command line than launching ( Run as... ) from eclipse...
6 lines of output were printed, each line is around 120 characters.
each line is a perf result ranges from 50ms to 300ms.
The total time is a little more than 2 seconds.
"much slower" here means, for certain operations ( function call ), I see 20ms vs 300 ms.
After running on console once, the speed on eclipse catches up!
After I change and build the code in eclipse, the speed on CL will drop if I don't rebuild it with command line.
Looks like some hotspot information is only generated with CL...
Maybe it is just the eclipse console that is slower than your operating systems console?
Plus, at a total runtime of ~2 seconds, your benchmark probably is just super inaccurate.
Most likely the culprit is memory usage as a result of Eclipse loading, with the possibility that Eclipse is also doing something additional to the executable like swapping class loaders, or starting the java debugger.
I would say the most likely answer however is simply: Eclipse uses a lot of resources, especially memory, and is starving the system a bit, leading to swapping, and decreased performance. YMMV, and there's no guarantee I'm right without seeing your system, it's just my best guess.
I do agree with other comments that Eclipse is doing something when running the application and printing the console.
Eclipse has its own compiler (usually referred as Eclipse JDT) which supports incremental compilation. There is a possibility that the binary compiled by Eclipse is not optimized as it is compiled by javac.
These two compiler serves different purpose, JDT mainly enable Eclipse to provide state-of-art refactoring and auto-completion, and javac spends a lot of effort doing optimization.
I would say it's understandable that the application would run slower with all the Eclipse baggage underneath. Eclipse spawns the JVM process as a child and I am sure still does its own 'magic'.
I find java starts up and runs practically instantly for me - but javac takes a few seconds, and ant makes it slower again. It's only a few seconds, but my edit-compile-test loop would be smoother without it. :-)
BTW: I've already used vim's ":make" with ant.
Is there a way to speed up javac and/or ant? I'm thinking of special switches, or tricks? Or maybe an alternative java compiler (I'm using 1.6, in linux)
Eclipse does that for you ... but it's probably a bit big as a "patch" for your problem.
That aside, you can roll your own compiler plugin. There are two approaches:
Run the java compiler from within ant (instead of creating a new process). Not sure if ant already does that; if not, that will save you a bit of time. Look at the Java 6 compiler API for details.
Run javac in a server process which listens for options on a socket. In ant, send the process the command line and wait for the output to be sent back. Saves you starting a new process all the time.
Try to use the eclipse compiler. Unlike the original javac, the Eclipse compiler is pretty good at "ignoring" errors, so it can produce class files even when they contain errors. That doesn't seem to mean much but it allows you to compile all the time in the background. When you do your last save (wrapping everything up), the compiler will have been able to compile everything else and will just have to look at a single file.
Google found these two (I haven't tried either yet)
javac -J-client -J-Xms100m -J-Xmx100m <src>
JBrownie "monitors Java sourcecode and automatically recompiles any files found changed" along the lines of Aaron Digulla's (2)
I can strongly recommend using a suitable IDE with Java as the productivity increase with using an editor which knows about your program is immense. Think of "goto the line containing the defintion of the variable/class/field the cursor is on", "rename this class and all references to it", and all other kinds of nice things. If you are annoyed with the time it takes to invoke Java, you might be ready :)
You may want to have a look at JavaRebel
I point all of my output files to a ramdisk that I create with this utility. It speeds up builds a fair bit (Though not to a magical extent) since almost everything is in memory. It's most noticeable when doing a 'clean' build which becomes almost instant.
anyone have any experience using this?
if so, is it worth while?
I just used jdb for the first time yesterday and am really pleased with the results. You see, I program in Eclipse on my laptop, then deploy to a VM to make sure the whole shebang still works. Very occasionaly, I'll have to work on something that gets executed standalone, as a commandline. These things sometimes need debugging.
This has always been a problem, because I don't want to go to the trouble of installing Eclipse on the VM (it's slow enough already!), yet I don't know of an easy way to get it to connect to my commandline-running class before it finishes running.
jdb to the rescue! It works a treat - small and functional, almost to the point where it is bare... this forces you to apply your mind more than you apply the tool (like I said here).
Make sure to print out the reference (solaris, windows, java 1.5 - I think they're all about the same, really) and have your source code open and browsable on your second screen. I hope you have a second screen, or you'll be alt-tabbing a lot.
Assume your program is started by the following command:
java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address=<port> <class>
You can attach to this process by jdb:
jdb -attach <port>
In some cases you need to use the following command .
jdb -sourcepath \.src -connect com.sun.jdi.SocketAttach:hostname=localhost,port= <port>
JDB is incredibly difficult to use. Placing System.outs or using an IDE debugger will produce better results. And for the more interesting features (e.g. tracking threads, heap size, etc.), you can get the information graphically with the JConsole tool.