Show Posts
|
|
Pages: [1]
|
|
1
|
Game Development / Performance Tuning / Re: JRockit optimizations
|
on: 2005-03-02 15:05:13
|
Hi, Noticed on Swing chat transcript ( http://java.sun.com/developer/community/chat/JavaLive/2005/jl0215.html): markyland: Are there any plans to allow Swing applications to be compiled natively?
Scott Violet: The closest thing I can say we're looking into is persisting compiled code between runs of the JVM. For example, each time you run your application we end up compiling a lot of the same methods; if this were cached it could conceivably speed things up. Whether or not something like this makes it in depends upon the results we get.At least Sun discovers that keeping compilation results or profiling can benefit to multiple runs (or has IBM a patent for using this technique in REXX 20 years ago?)... Next time (in 10 or 15 years?), perhaps they'll discover stack allocation for small short lived objects with escape analysis...
|
|
|
|
|
3
|
Discussions / Miscellaneous Topics / Re: Sun's crappy generic implementation
|
on: 2005-01-20 18:22:23
|
I see a lot of whining, when the reality is - it doesn't bloody matter. Generics does enough good, and only has a couple, well known, issues that ultimately are never going to affect my code. So I'm happy with it.
Never say you will never be bitten by Java 5 code! Have a look at Sun Generics forum to see strange new things... A few examples, just to tease you: 1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Problem { public static void main(String[] args) { java.util.LinkedList<String> list1 = new java.util.LinkedList<String>(); list1.add("foo"); list1.add("bar"); list1.remove("bar"); java.util.LinkedList<Integer> list2 = new java.util.LinkedList<Integer>(); list2.add(3); list2.add(7); list2.remove(7); } } |
OK, that's not generics only but also autoboxing! This program fails with IndexOutOfBoundsException because it does not translate list2.remove(7) as list2.remove(new Integer(7)), just as it would do for list2.add(7). Also, this one is cool: 1 2 3 4 5 6 7 8
| Integer x = 2; Integer y = 2; Integer a = 200; Integer b = 200; System.out.println("x == y : " + ( x == y )); System.out.println("a == b : " + ( a == b )); |
Or generic presumably simplifying the code and making it safer. I like this definition: 1
| public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) |
Explanation: Including "extends Object" is an ugly trick that causes the compiler to erase the method to "Object min(Collection coll)" instead of "Comparable min(Collection coll)". This would make the erased method compatible to J2SDK 1.4... Yes, new Java version is a bastard one and not all marketing hype Sun is employing to say cleaner, safer Java hides the truth: the baby is ugly!
|
|
|
|
|
9
|
Game Development / Performance Tuning / Java becoming a non-deterministic runtime?
|
on: 2004-02-27 14:49:30
|
Hi, I don't know if you feel like me, but I think that Sun is turning Java in a non-deterministic language. I'll try to explain... I've been used to languages where one could say that a loop control structure is O(N). In ol' BASIC days, took a time proportional to the value of N (at least when the code in the loop is constant and the compiler does not do too much agressive code removal). There are other parameters like the platform, but at least, you could do an algorithmic analysis and optimize your source code on the paper without event running it. Now, with the Java runtime, the performance of some code depends on soo many runtime parameters: - The JVM type (Sun, IBM, BEA...) - The JVM compiler type: Hotspot -server or -client. Has the loop run enough to raise the hotspot compiler? - The JVM parameters: -incgc and surch -X non-portable options. - And of course platform: you don't write the same code for J2ME or J2SE. On J2ME, you MUST manage your objects allocations. The programmer has less options to write optimized code and the performance depends on the runtime environment. As a consequence, when you do a change in your code, you can't predict the impact it'll have on performance. Remember when code was cluttered with object pools to compensate for the garbage collector poor performance? Now, I fear to write clean code, with correct performance with today VM (and its tuned runtime parameters) and to discover in a few years that the code+tuning parameters are no more valid with current VM... Nowadays, you take care not to create objects in a critical time loop, but how will run this code when JVM implement escape analysis or other techniques?
|
|
|
|
|
12
|
Game Development / Performance Tuning / Re: Problem with OutofMemoryError
|
on: 2004-02-18 14:32:20
|
|
Hi,
I've had a similar problem today. I've found that one of our Web applications won't run if the JVM is not started with the tuned parameters -Xmx256M -Xms128M -XX:NewSize=60M -XX:MaxPermSize=128M -XX:MaxNewSize=120M.
If these parameters are not set, I get a OutOfMemoryError in some pages, even if I've got a lot of memory on that server. I've always thought that the JVM would do the best effort to manage memory, and that these errors would happen on badly tuned JVM, if not on default configuration...
This happens consistently with JDK 1.3.1_09 and 1.4.2_03!
|
|
|
|
|
13
|
Game Development / Performance Tuning / Re: Expanding Heap
|
on: 2003-12-18 18:55:58
|
Hi Drew, If your application is running on a PC, you can try the profiler in the Sun JVM. Try for help. There is an option to display all objects still in memory when the application ends ( 1
| java -Xrunhprof:heap YourClass |
and look at the content of the java.hprof.txt file for results). Well, graphical memory analyzers (like the Eclipse profile plugin) give you more than that, but this one is available almost everywhere...
|
|
|
|
|
16
|
Game Development / Shared Code / Re: REQUEST: Portable key handler
|
on: 2003-05-31 21:50:40
|
The end of the code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
| class FlexibleQueue { private final int _initialSize;
private final int _increment;
private int _start = 0;
private int _end = 0;
private int _size = 0;
private Object[] _content;
public FlexibleQueue() { this(10, 5); }
public FlexibleQueue(final int size, final int increment) { _content = new Object[size]; _initialSize = size; _increment = increment; _start = 0; _end = 0; _size = 0; }
public void addElement(final Object object) { synchronized (_content) { if (_size == _content.length) { expandFullQueue(); } _content[_end] = object; _end = (_end + 1) % _content.length; _size += 1; } }
public Object removeElement() { synchronized (_content) { Object result = _content[_start]; _start = (_start + 1) % _content.length; _size -= 1; return result; } }
public Object readElement() { synchronized (_content) { return _content[_start]; } }
public int size() { synchronized (_content) { return _size; } }
public int capacity() { synchronized (_content) { return _content.length; } }
public void reset() { synchronized (_content) { _content = new Object[_initialSize]; _start = 0; _end = 0; _size = 0; } }
public String toString() { final StringBuffer buf = new StringBuffer(); buf.append(getClass().getName()); buf.append("[size="); buf.append(_size); buf.append(", content={"); if (_start > _end || _size == _content.length) { for (int i = _start, size = _content.length; i < size; i++) { buf.append(_content[i]); if (i != _size - 1) { buf.append(", "); } } for (int i = 0; i < _end; i++) { buf.append(_content[i]); if (i != _end - 1) { buf.append(", "); } } } else { for (int i = _start; i < _end; i++) { buf.append(_content[i]); if (i != _end - 1) { buf.append(", "); } } } buf.append("}]@"); buf.append(hashCode()); return buf.toString(); }
private void expandFullQueue() { final Object[] tmpContent; tmpContent = new Object[_content.length + _increment];
if (_start > _end || _size == _content.length) { System.arraycopy(_content, _start, tmpContent, 0, _content.length - _start); System.arraycopy(_content, 0, tmpContent, _content.length - _start, _end); } else { System.arraycopy(_content, _start, tmpContent, 0, _end - _start + 1); }
_start = 0; _end = _content.length; _content = tmpContent; } }
|
|
|
|
|
|
17
|
Game Development / Shared Code / Re: REQUEST: Portable key handler
|
on: 2003-05-31 21:49:33
|
Hi, As a start, here is some code to filter the surnumerous KeyReleased events under linux. The ONE advantage: - It's portable code using JDK 1.1.8 API. The disadvantages: - It creates on thread by KeyListener it manages. - The filtering is based on a delay. If no more event is received during a delay, then the KeyReleased must be the last of the sequence and is sent to the KeyListener. If the delay is chosen too big, there is a lag before the last event is sent; if too short, some KeyReleased events can escape the filter... - The choice of the delay depends on the platform. 100 ms seems to be OK on the Zaurus, but creates problems when accessing it remotely with VNC. TODO: - Define exactly what we need (in another post) for cross-platform key processing. - Support dumb keys like [Shift] which repeat under Windows but don't under linux. - Put the delay in a system property, or at least in a parameter of the constructor... The begining of the code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
| import java.awt.event.*; import java.awt.*;
public class Test { public static void main(String[] args) { Frame fr = new Frame(); TextField l = new TextField("Enter keys"); fr.add(l); fr.pack(); fr.show(); l.requestFocus();
fr.addWindowListener(new WindowAdapter() { public void windowClosing(final WindowEvent evt) { System.exit(0); } }); if (args.length > 0) { l.addKeyListener(new KL()); } else { l.addKeyListener(new KeyHandler(new KL())); } }
private static class KL implements KeyListener { public void keyPressed(KeyEvent e) { System.out.println(e); }
public void keyReleased(KeyEvent e) { System.out.println(e); }
public void keyTyped(KeyEvent e) { System.out.println(e); } } }
class KeyHandler implements KeyListener { private final KeyListener _listener; private final KeyHandlerThread _thread; public KeyHandler(final KeyListener listener) { _listener = listener; _thread = new KeyHandlerThread(100L); _thread.start(); } protected void finalize() throws Throwable { _thread.stopHandler(); }
public void keyPressed(final KeyEvent evt) { _thread.addEvent(evt); }
public void keyReleased(final KeyEvent evt) { _thread.addEvent(evt); }
public void keyTyped(final KeyEvent evt) { _thread.addEvent(evt); }
private void dispatchKeyEvent(final KeyEvent evt) { switch (evt.getID()) { case KeyEvent.KEY_PRESSED: _listener.keyPressed(evt); break; case KeyEvent.KEY_RELEASED: _listener.keyReleased(evt); break; case KeyEvent.KEY_TYPED: _listener.keyTyped(evt); break; default: throw new RuntimeException("Unhandled key event: " + evt); } } private class KeyHandlerThread extends Thread { private final FlexibleQueue _events = new FlexibleQueue(); private volatile boolean _handleKeys; final private long _delay; KeyHandlerThread(final long delay) { super("KeyHandlerThread"); setDaemon(true); _delay = delay; _handleKeys = true; } public void run() { while (_handleKeys) { synchronized (this) { try { if (_events.size() == 0) { wait(); } } catch (InterruptedException ie) { } if (_events.size() > 0) { KeyEvent event = (KeyEvent) _events.removeElement(); if (event.getID() == KeyEvent.KEY_RELEASED) { try { wait(_delay); } catch (InterruptedException ie2) { } if (_events.size() > 0) { KeyEvent event2 = (KeyEvent) _events.removeElement(); if (event2.getID() == KeyEvent.KEY_PRESSED && event.getKeyChar() == event2.getKeyChar()) { dispatchKeyEvent(event2); } else { dispatchKeyEvent(event); dispatchKeyEvent(event2); } } else { dispatchKeyEvent(event); } } else { dispatchKeyEvent(event); } } } } } void stopHandler() { _handleKeys = false; } void addEvent(final KeyEvent evt) { synchronized (this) { _events.addElement(evt); notifyAll(); } } } } |
|
|
|
|
|
18
|
Game Development / Shared Code / Re: REQUEST: Portable key handler
|
on: 2003-05-28 20:55:47
|
Thinking more of it, that's not a trivial problem... What sequence of events (and value) should you obtain if you press and hold two keys?  Under Windows, I see a KeyPressed and KeyTyped for both keys, at the begining of the sequence; then KeyPressed + KeyTyped for only one; and KeyReleased for both. The key repeat mecanism does not make it simple to go up right when the user presses at the same time [^]+[>] 
|
|
|
|
|
19
|
Game Development / Shared Code / Re: REQUEST: Portable key handler
|
on: 2003-05-28 15:26:34
|
Hi, Because the Sharp Zaurus is running linux  . And the bug occurs with Esmertec/Insignia Jeode and Sun Personal Profile JVMs. It makes me wonder if there are people writing games on linux workstations in Java 
|
|
|
|
|
20
|
Game Development / Shared Code / Re: REQUEST: Portable key handler
|
on: 2003-05-28 14:52:18
|
Hi, @swpalmer, Yes, the bug numbers in Sun Database are 4153069 and 4839127. And Sun does not know how to solve it easily... @princec Can you confirm that LWJGL handles the sequence of events correctly, on both platforms Windows and linux (the bug is visible on linux; Windows is correct according to the doc). Press and hold a key and look at the KeyEvent generated when the typomatic key-repeat runs. On Windows you get: pressed typed pressed typed pressed typed pressed typed pressed typed released On linux, you get: pressed typed releasedpressed typed releasedpressed typed releasedpressed typed releasedpressed typed released You can use the code from http://developer.java.sun.com/developer/bugParade/bugs/4839127.htmlIf you confirm that it works in LWJGL, I'll look at the code. But I want a Java-only solution to use on a J2ME platform...
|
|
|
|
|
21
|
Game Development / Shared Code / REQUEST: Portable key handler
|
on: 2003-05-28 00:52:34
|
Hi, On linux, key management in games is not easy due to a bug (or is it a linux feature?): http://developer.java.sun.com/developer/bugParade/bugs/4153069.htmlOn linux, the keyReleased() event is fired, when the user holds a key down, even if the key is not released. This makes it difficult to determine when a key is actually released. On Windows, the keyReleased event is sent only at the end of the keyPressed() / keyTyped() sequence, as documented. I think it would be good to have a bit of portable code to handle both configurations. Who has already had troubles with this situation?
|
|
|
|
|
24
|
Game Development / Performance Tuning / Re: Strange double calculation result with JDK1.4.
|
on: 2003-04-22 20:42:15
|
Hi leknor, Thanks. I've forgotten to say that I had already tried the strictfp modifier and it does not help: I got the same result on my workstation... That's really strange, because I can switch the JVM in Eclipse (or on the command line) at will, and I get a different result only on that test! And on the Zaurus with FP emulator, I get it right! But I have no another PC where to try another JDK1.4.2 setup and check if it's a configuration problem... 
|
|
|
|
|
25
|
Game Development / Performance Tuning / Strange double calculation result with JDK1.4.2
|
on: 2003-04-22 18:05:23
|
Hi, I've written a small benchmark to test the processing power of the new Sharp Zaurus PDA models. http://www.alterna.tv/zjb/Zjb.javaThen I wanted to compare the result with my workstation, with JDK 1.4.2 Beta. And I was really surprised to discover that the Pi calculation was giving a wrong result: Pi=3.141 3934230804443! This only happens when running the whole program AND with JDK1.4.2. I had no problems when: - using other JDK: 1.4.1, 1.4.1_01, 1.3.1_01, 1.1.8 - using other platforms: PC, Zaurus - extracting the Pi calculation fragment, with/without previous code... So it must be: 0) A bug in my code, but I can't pinpoint it. 1) A problem in my workstation configuration. Apart from setting up JDK1.4.2, nothing new has happened recently. 2) A bug in the platform/OS. Could a new Win2K hotfix have broken a fix for a hardware problem, and Sun coincidentaly has removed the support from the JVM  My platform is a Win2K SP3 2xPII 350MHz. 3) A normal bug encountered in Beta software. Never play with Beta software keep saying my mother  4) An alien cause not listed in software development courses... Could someone with a 1.4.2 JDK setup try my code and check the Pi value?There's no need reporting the problem to Sun if it's not point 2) or 3). As a bonus, you'll can compare the performance of your workstation with a Zaurus SL-5500 PDA running Jeode http://www.alterna.tv/zjb/zjb-SL-5500.png or Sun Personal Profile http://www.alterna.tv/zjb/zjb-SL-5500-Sun.png.
|
|
|
|
|
26
|
Game Development / Performance Tuning / Re: Inlining
|
on: 2003-04-22 17:30:27
|
Short form: only use final when it makes sense from a design perspective. Shortest form: Put final everywhere and only remove it when the compiler complains 
|
|
|
|
|
|
Add your game by posting it in the WIP section,
or publish it in Showcase.
The first screenshot will be displayed as a thumbnail.
|
|