Eclipse memory setting and other tricks

N

NOBODY

Hi,

1-
First, don't give eclipse more heap, because it doesn't need it, or at least don't give too much.
If you give a JVM more heap, IT WILL GRAB IT, but only to pile more garbage
and the Full GC will just take longer, especially because it must swap in
from virtual memory before being able to run finalizers if any.
The reason why you feel it works better, is because it fullgc's less frequently.

The only bug is the JVM that doesn't release unused heap yet. (maybe jdk 1.5...)

Write a small program that invokes the elipse main and give
yourself a way to invoke System.gc() (ui button, read stdin for "gc", whatever...)
and report the time it took, and the before/after memory used/free/total (see java.lang.Runtime)
The reason I suggest that, is to monitor in how much heap eclipse really fits in.
If you gc and never sees more that 30 megs. you should be fine with the default 64 meg.

See ExtraSimpleConsoleDebugger.java below.
Feel free to add commands like listing threads, system properties, current time, etc...


2-
Do not minimize your eclipse window. What?
Yes that's right. Windoze has this bad habit, although some think it's nice,
to schedule parts of a foreground app memory for swap out to paging file as soon as minimized.
If you keep eclipse running over night, you know what I mean...
If you got the GC trick above, leave the eclipse window minimized overnight and
without restoring the window, invoke gc when coming in the morning.
You should get 1-3 minutes GCs! (it is swapping in). (2nd tip: close eclipse everyday...!)

Another trick during day is to keep eclipse de-maximized but not minimized, in a window that I
resized to barely have the title bar, and I toss it in a corner.
This way, it is not swapped out, and you can totally see your desktop.
Kind of like those new window manager, that rolls up windows in a thin bar.

3-
Hotspot jit compiled code takes place too! If eclipse has been running for hours, it
is then fairly jit compiled. The default jit threshold is 1500 invocations. So the trick,
(if you worry about ram but not CPU) is to disable the JIT, or set the threshold very high.
(-Xint to disable, or -XX:CompileThreshold=####)
On the opposite, if you want performance and got plenty of ram, set it lower.
But 1500 is fairly low already. Just remember that JIT compiling take a bit of extra time also,
So a too-low threshold will slow down even more the startup.


4-
GC options.... I tried so many, but frankly, on a single CPU, you can't do much tuning.
You can try. Maybe your hyperthreaded CPU on winXP will kick in and give good results...


5-
Here is my eclipse launch batch file:
fyi: I just update my eclipse by copying my workspace folder to the freshly unzipped eclipse sdk.
At first run, it converts anything it has to, and recreate the .config/ folder, and exits.


Don't worry, you run eclipse a 2nd time. That double start is invisible when you use eclipse.exe.


Hope this helps.


(And I hope your reader doesn't wrap lines...)


----------------------------------------------------------------

@echo off
rem set idepath=C:\java\eclipse_3.0_i20030806
rem set idepath=c:\java\eclipse_3.0_i20040106
rem set idepath=c:\java\eclipse_3.0_i20040121
set idepath=c:\java\eclipse_3.0M7
rem set idepath=C:\java\eclipse_3.0_i20040226

rem ----------------------------------------

rem set jvmpath=C:\java\j2sdk1.4.1\bin
set jvmpath=C:\java\jdk14\bin
cd /d %idepath%

set jvm=%jvmpath%\java.exe -showversion

rem set memoryspec=-Xms32m -Xmx128M -XX:NewRatio=8 -XX:SurvivorRatio=4
rem set memoryspec=-Xms32m -Xmx64M -XX:NewRatio=8 -XX:SurvivorRatio=4
rem set memoryspec=-Xms32m -Xmx96M


rem set jitspec=-XX:CompileThreshold=10
rem set jitspec=-XX:CompileThreshold=5
set jitspec=

rem set gcspec0=-verbosegc -XX:+PrintGCDetails -XX:+PrintTenuringDistribution -XX:+DisableExplicitGC
set gcspec0=-verbosegc


rem (throughput) UseParallelGC
rem set gcspec=-XX:+UseParallelGC

rem (low pause concurent) concurent mark-sweep
rem set gcspec=-XX:+UseConcMarkSweepGC

rem (low pause concurent) concurent mark-sweep with concurrent remark
rem set gcspec=-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled

rem (low pause concurent) concurent mark-sweep with concurrent remark with defrag oldgen
rem set gcspec=-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection

set gcspec=

rem ------------------------------------------

@echo on
%jvm% %memoryspec% %jitspec% %gcspec0% %gcspec% -cp %idepath%\startup.jar org.eclipse.core.launcher.Main org.eclipse.ui
@echo off

rem With commandline/UI tool (to run GC and get memory stats):
rem %jvm% %memoryspec% %jitspec% %gcspec0% %gcspec% -cp c:\java\prog\tools.jar;%idepath%\startup.jar ExtraSimpleConsoleDebugger -is 2222 org.eclipse.core.launcher.Main org.eclipse.ui





----------------------------------


import java.io.*;
import java.lang.reflect.Method;
import java.net.*;


public class ExtraSimpleConsoleDebugger {
static String EOL = "\r\n";//System.getProperty("line.separator");

private PrintStream cd_ps_out = null;
public ExtraSimpleConsoleDebugger(PrintStream output) {
cd_ps_out = output;
}

void gc() throws Exception {
memInfo();
long t1 = System.currentTimeMillis();
System.gc();
long d = System.currentTimeMillis() - t1;
cd_ps_out.println("System.gc(): "+d+" ms");
memInfo();
cd_ps_out.flush();
}

void memInfo() throws Exception {
Runtime r = Runtime.getRuntime();
long f = r.freeMemory();
long t = r.totalMemory();
cd_ps_out.println("USED=" + (t - f)/1000 + "k, FREE=" + (f/1000) + "k, (TOTAL=" + (t/1000) + "k)");
cd_ps_out.flush();
}


public static void main(String args[]) throws Exception {
if(args.length<1) {
System.out.println("Arguments:");
System.out.println(" [-is <port>] [classname [std arguments]]");
System.out.println("where:");
System.out.println(" port tcp port to start input server on");
System.out.println(" classname classname on which the main(String[]) method will be invoked");
System.out.println();
}

String classname = null;
String[] arguments = null;
int isport = 0;

int i = 0;
while(i<args.length) {
if(args.equals("-is") && args.length >= (i+1)) {
isport = Integer.parseInt(args[i + 1]);
i += 2;
} else {
classname = args;
arguments = new String[args.length - i - 1];
for(int j = 0; j < arguments.length; j++) {
arguments[j] = args[i + j + 1];
}
break;
}
}


if(classname!=null) {
if(isport>0)
ExtraSimpleConsoleDebugger.startInputServer(true, isport);
invokeMain(classname, arguments);
} else if(isport>0) {
System.out.println("---TEST MODE---");
ExtraSimpleConsoleDebugger.startInputServer(false, isport);
}

}

public static void startInputServer(boolean daemon, int port) {
CommandInputServer cis = new CommandInputServer(port);
cis.setDaemon(daemon);
cis.start();
}

static void invokeMain(String className, String[] sa) throws Exception {
if(sa == null)
throw new IllegalArgumentException("String[] cannot be null");

Class c = Class.forName(className);
Class saClass = (new String[0]).getClass();
Class[] ca = new Class[]{saClass};
Method m = c.getMethod("main", ca);
m.invoke(null, new Object[]{sa});
}

//============================================
// INNER CLASSES
//============================================

static class CommandInputServer extends Thread {
private int cnt = 0;
int port;
ServerSocket ss;

CommandInputServer(int port) {
super("CD-InputServer:" + port);
this.port = port;
}

public void run() {
try {
ss = new ServerSocket(port);
while(true) {
Socket s = ss.accept();
InputSession is = new InputSession(this, cnt++, s);
is.start();
}
} catch(Exception e) {
e.printStackTrace();
} finally {
try {
ss.close();
} catch(Exception e) {
}
}
}
}

static class InputSession extends Thread {
CommandInputServer cis;
Socket socket;
int sessionNumber;

InputSession(CommandInputServer cis, int sn, Socket s) {
super("CD-InputSession[" + sn + "]:" + cis.port);
this.cis = cis;
this.sessionNumber = sn;
this.socket = s;
}

void help(PrintStream ps) {
ps.println();
ps.println("gc : run System.gc()");
ps.println("m : show memory info");
ps.println("endserver : ends the Session creator server (on accept port)");
ps.println("q : quit this session");
}

public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream(), true);
ps.println();
help(ps);
ps.print(getName() + ">");
ps.flush();

ExtraSimpleConsoleDebugger cd = new ExtraSimpleConsoleDebugger(ps);

for(String line = br.readLine(); line != null; line = br.readLine()) {
String trimmed = line.trim().toLowerCase();
ps.println(trimmed);

if(trimmed.equals("?")) {
help(ps);
} else if(trimmed.equals("gc")) {
cd.gc();
} else if(trimmed.equals("m")) {
cd.memInfo();
} else if(trimmed.equals("endserver")) {
cis.interrupt();
cis.ss.close();
} else if(trimmed.equals("q")) {
break;
} else if(trimmed.length()>0){
ps.println("Unknown cmd: "+trimmed);
}

ps.print(getName() + ">");
ps.flush();
}

br.close();
ps.close();
socket.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top