TeachJava Is Over

I just finished my almost day-long presentation of the Marine Biology Simulation here at TeachJava. I had a lot more material than I could cover, but I’m still satisfied with the presentation. The discussion about our design choices was very fruitful. The discussion lead me to emphasize error prevention versus error recovery. That is something that I should add to the material.

Now I have a long weekend, I’m looking forward to finally getting my new computer to a point where I can work with it. Woohoo :)

Share
Posted in Research, Uncategorized | Leave a comment

Print This Post Print This Post  

Last Few Days

I’ve finished updating the presentations for tomorrow. I’ll first compare the AP MBS and the Rice MBS, then let our TeachJava participants work on the assignment for a little bit.

Unfortunately, I still haven’t had time to really set my new computer up, and so I haven’t been able to work on it. I have no clue how fast it is, but it feels fast. It boots amazingly quickly and is so quiet, I usually don’t even hear it. I moved the second hard drive into the new computer yesterday. Unfortunately, for some reason I lost the documents on my main data partition. Somehow it went from an NTFS partition to an unknown partition, and I can’t revive it. I have a very recent backup, but it didn’t include any movies and TV shows I had downloaded. That makes me a bit sad, but it’s replaceable.

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post  

Busy Week

This week is TeachJava! here at Rice. It’s a Java seminar targeted mainly at high school computer science teachers. It runs from 8:30 to 5, so I’m away from home from shortly before 8 AM until about 5:30. I don’t really get much done right now. I haven’t been able to install anything on my new machine; in fact, I swapped the computers back and am working on my old machine now. The new one works, but there’s nothing on it to work with yet.

So far, the programming exercises have been going very smoothly. I must commend Dr. Cartwright, Dr. Nguyen, Dr. Wong, and the guys working on DrJava for that — they’ve put a lot of effort into this. Since I haven’t had to run around a lot, I’ve actually managed to finish a nice tool that works with Java class and jar files. It scans for classes, methods, and fields with certain access specifiers (public, private, protected, abstract, native, and so on). The command line syntax was inspired by chmod:

PropertyScanner <infile> [<properties> [<properties> [<properties> ...]]]

where

<properties> = c-* | c{+|-}<cflags>
             | m-* | m{+|-}<cflags><mflags>
             | f-* | [f{+|i}<cflags><fflags>

and the flags consist of one or more letters:

<cflags> - class flags: PFSIA (public, final, static, interface, abstract)
<mflags> - method flags: prosfynai (public, private, protected, static,
           final, synchronized, native, abstract, strict)
<fflags> - field flags: prosfvt (public, private, protected, static, final,
           volatile, transient)

If a certain flag is not set to either + or -, then it does not matter if the corresponding access specifier is present. If, however, a flag is set to +, then the access specifier must be present, and if it is set to -, it must not be present. If {c|m|f}-* is used, then no output at all is generated for classes, methods, or fields, respectively.

So, for example, PropertyScanner Test.class would output all classes, methods, and fields in Test.class. PropertyScanner rt.jar c-* f-* m+Fny m-As would output only native synchronized (+ny) and non-static (-s) methods that are in final (+F), non-abstract (-A) classes in rt.jar. The tool is pretty useful in finding special cases inside rt.jar.

I’ve also started working on the instrumentation strategy to convert non-native synchronized (static) methods to unsynchronized (static) methods containing a synchronized block that uses this (or this.getClass() for static methdos) as lock.

I really need to work on my Rice MBS presentation for Friday, though. I’ve edited the web page, but I still need to update the presentations and get everything into a coherent form. Since I’ve presented related material both at SIGCSE 2004 and OOPSLA 2004, there is a bit of an overlap.

I really wanted to finish doing that today, but a friend and I got dinner together. He mentioned an idea he’d had, I mentioned one I just had, and off we went to a five-hour brainstorming session. I’m not going to disclose here what we talked about, but this brainstorming was probably the most successful session I’ve ever had. We were blurting out ideas so quickly, neither of us could write them down fast enough. I wish we had just voice-recorded it.

Ok, now it’s off to bed for me. Only four hours of sleep again :-S

Share
Posted in Concurrent Unit Testing, Research, Uncategorized | Leave a comment

Print This Post Print This Post  

New PC… (4) :)

Yay. Windows 2003 Server is finally installing on the SATA drive. After finding out that it indeed was a problem with the drive and the motherboard, a more guided search revealed an article on the Western Digital homepage that described how to fix the problem. The VIA VT8237 doesn’t support autospeed negotiation, so the drive had to be fixed at 150 MB/s by changing a jumper.

Now I’m finally where I wanted to be on Saturday already, and I can begin to install everything and move data between the two computers. I’ll keep you posted.

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post  

New PC… (3) :(

On Saturday, I went to Directron again to pick up the computer. This time, it was actually ready. I asked for them to remove the $27 for assembly from the bill to make up for the hassle; they did not remove it, but gave me store credit for it. That is satisfactory for me.

I didn’t want having to go back a third time, so I checked the computer in the store. It was well built and had all the components I had ordered. It also contained a graphics card, some GeForce 6400 with 64 MB RAM and TV-out, I think. I’m not sure if I’ll use it, though. It’s newer than any of my other graphics cards, but it only has one monitor output. At least my primary computer needs to have two.

At home, I powered it up, then swapped out the graphics card for my GeForce 5200 with two monitor-outs, put in my CD and DVD drives. I re-routed some of the cables. It’s really well set up now, good airflow, and very quiet.

Then I popped in the Windows 2003 Server CD and hit a wall. To recognize the SATA controller, I needed to put drivers on a floppy, and I didn’t have a floppy drive in that machine. So I took out the drive from my old machine and put it in the new one, then used the Asus CD to create a driver disk… which failed. I downloaded the drivers from the web, copied them, and that finally worked.

Now the Windows setup detected the drive and let me partition it. It started copying files, did the first reboot, displayed the Windows 2003 Server loading screen with the nice [ ###–> ] bar and did nothing.

That’s where I still am. After two days, I still haven’t been able to install Windows on my SATA drive. I’m working on freeing up a regular parallel ATA drive so I can check if the Windows setup will work on that. Unfortunately, it’s TeachJava! this week, so I won’t get to it until tonight. I’ll also try to create a slipstreamed Windows 2003 Server + Service Pack 1 installation CD that will also include the SATA drivers. Maybe there’s something wrong with the drivers on the floppy.

If someone has a clue what’s going wrong, please let me know.

Update

So it definitely has something to do with the Western Digital WD1600JD 160 GB 7200 RPM 8MB cache SATA drive. I put in a PATA drive and removed the SATA drive and it worked. If I left the SATA drive plugged in but didn’t use it as system drive for the Windows installation, it would not work. Maybe it is some kind of incompatibility between the Asus A8V board and the drive. I’ll keep on testing.

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post  

No Clue About Stack Frame Crashes

Earlier I hypothesized that incorrect line number information might be the cause of the stack frame crashes. I just spend about half an hour comparing the line number information in instrumented and non-instrumented class files to see if I updated the line number information incorrectly.

Unfortunately, I haven’t found anything. In all the classes I’ve looked at, the old and new line numbers point to the same opcode, modulo insertions, of course. I’m happy that I apparently did a good job when I wrote the code, but I’d much rather be disappointed by myself and now know how to fix the problem than to have no clue at all now.

Back to square one regarding this issue. Of course, it could also be some special case that I have not considered yet. Fortunately, I can continue working on other things.

Share
Posted in Concurrent Unit Testing | Leave a comment

Print This Post Print This Post  

Argh!

I’m a little bit angry right now. I ordered the computer on Monday, called on Tuesday for an assembly estimate. The computer was supposed to be done on Wednesday. Wednesday morning I got a call that some parts were not in yet and it would not be done until Thursday. No problem.

Thursday morning I called to confirm that the computer was done. I was told it would be done after 3pm. I couldn’t find anyone to drive me out there on Thursday, so I was going to pick it up Friday at noon. The computer was done, right, so what did it matter?

Today I called again and talked to a guy, Nash. He said their server was down right now, but he would call me back. He did and confirmed that the PC was ready to be picked up. I got there at 1:15pm, they wasted about 30 minutes of my time, then — and only after inquiring again — Zac, the salesperson I talked to, said the computer had not been assembled yet and won’t be until tomorrow. He even gave me this “You talked to customer service. I don’t work in that department” line.

Listen, folks at Direction: If someone in your company tells me my order is ready, it better be ready. I don’t care who I talked to. If someone in your company fucks up, you have fucked up too, and I will hold you responsible for it.

If I experience any problems tomorrow, I will rip your heads off.

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post  

Stack Frame Crashes

I was just thinking about the representation again. I think the representation with the two hash maps is right, but now I’m worried about inconsistencies between the data I keep and the data I get from JPDA. Right now, I update my data in the hash maps. Maybe I should always replace my data with fresh, guaranteed-to-be-accurate data from JPDA whenever I get it. I think for now I’ll just add a few assertions to find out if inconsistencies occur.

While I was mulling this over, I had an idea why getting the stack frames of the threads may crash the VM after I’ve added in instrumentation of synchronized blocks: Whenever I instrument synchronized blocks, I change bytecode in a lot of places. Maybe I change the line number information that goes along with the bytecode incorrectly? I know that I do attempt to change it, but I should definitely go over it again.

Share
Posted in Concurrent Unit Testing | Leave a comment

Print This Post Print This Post  

Storage Considerations

After getting several things to work in the early morning ours yesterday, I’ve been cleaning a few things up in the thread monitor source. One thing I’m working on is the unification of the data representation.

Since I want as little interaction between the master and the slave as possible and since I want to avoid JPDA’s idiosyncracies regarding access and thread state — and also for pure ease of use (accessing remote data using JPDA is more than cumbersome) , I am duplicating some of the data structures and translating the data I get from JPDA mirrors.

There are basically two separate lists: a list of threads, and a list of locks (Java calls then monitors; so far, I have chosen to call them locks in order to avoid confusion between these monitors and my monitors — ThreadMonitor, ObjectMonitor, SynchronizedMonitor; I should probably do a thorough renaming of all the terms to get my terms in line with the rest of the world).

An entry in the thread list contains a list of owned locks and a reference to the currently contested lock. An entry in the lock list contains a list of waiting threads and a reference to the owning thread. It’s something like this (pseudocode):

class ThreadInfo {
List ownedLocks;
LockInfo contestedLock;
}

class LockInfo {
List waitingThreads;
ThreadInfo owningThread;
}

Now, when I change a value in one of the locks, for example, that change needs to be reflected in all the thread entries that somehow contain that lock, either as owned or as contested lock.

Right now, I’m going through the entries and I update them, but I’m not convinced I actually keep all of them up-to-date. I also think this might get complicated later. Conceptually, the thread and lock information should be singletons per unique ID, so maybe I should actually model it that way: The actual entries are stored in hash maps indexed by the unique ID, and the entries only store unique IDs that serve as indices into the hash maps:

class ThreadInfo {
List ownedLockIds;
Long contestedLockId;
}

class LockInfo {
List waitingThreadsIds;
Long owningThreadId;
}

HashMap threads;
HashMap locks;

Of course, this makes lookups a bit more tedious. You absolutely have to keep track of both lists separately, even if you don’t really care all that much for data consistency. A hybrid approach would be to store the thread and lock information in a hashmap, and also store copies in the entries but allow them to be out-of-date. Access to up-to-date information can be obtained through the hash map and the unique ID stored in the entry to be looked up:

class ThreadInfo {
List ownedLocks;
LockInfo contestedLock;
}

class LockInfo {
List waitingThreads;
ThreadInfo owningThread;
}

HashMap threads;
HashMap locks;

This approach tries to get the best of both worlds, but it incurs higher memory use and is possibly more confusing because there is more than one way to do something.

Any thoughts?

Update

I’ve decided to go with a variant of the second model. There’s just less that can go wrong with this implementation. I have changed the lists to sets, though. Each id should be present only once, so a set is a more natural representation here. The data structure now looks like this:

class ThreadInfo {
Set ownedLockIds;
Long contestedLockId;
}

class LockInfo {
Set waitingThreadsIds;
Long owningThreadId;
}

HashMap threads;
HashMap locks;

Share
Posted in Concurrent Unit Testing | Leave a comment

Print This Post Print This Post  

Frustrating

The last day has been frustrating again. Whenever I instrument the runtime for synchronized blocks, I’m getting the VM error I’ve mentioned earlier, but only when the thread monitor is attached. If I let the program run unmonitored, it works. If a runtime is used without instrumentation for synchronized blocks, it works even with monitor attached.

That seems to indicate that there’s some interaction between the synchronized blocks and the way JPDA attaches to the slave VM that I don’t understand and that’s not documented. I’ve spent hours commenting out one thing or another, experimenting with the order of things to figure out what exactly makes the slave VM hiccup.

I still haven’t been able to figure it out, but it has something to do with suspending and resuming the execution of the slave VM. Grr.

Update

Apparently the problem is caused by reading out the stack frames of the threads. Why this happens is a mysterium to me. It used to work before, when the runtime was not instrumented for synchronized blocks.

This might give me a chance to continue working, though. The stack frames aren’t necessary for the concurrent unit testing project, they would have been neat for a thread monitor, though.

All the work today made me realize that all the variables I am accessing from the thread monitor should probably be volatile. I am worried that the HotSpot VM decides to optimize and drop fields that I need. That also means writing my own data structure implementation for the synchronization point list, something that makes sense anyway. An automatically resizing ring buffer could be useful.

Also, my new PC should be ready for pickup tomorrow. Unfortunately, I haven’t found anyone who can take me there tomorrow afternoon yet. A trusted friend volunteered her lunch break on Friday already, though. Thank you :)

Share
Posted in Concurrent Unit Testing | Leave a comment

Print This Post Print This Post  

New PC… (2)

I noticed again how out of touch with the hardware world I have become over the last five years. In my order, I had picked a motherboard with four memory slots and decided to fill each with a 512MB module. I don’t anticipate needing more than 2GB, at least not if this computer will last anywhere near as long as my current one.

An acquaintance online was shocked I had done that. Didn’t I know the integrated memory controller only supports six banks (or three double-sided modules) at full speed? No, I didn’t. Having my DDR 400-priced memory run at DDR 333 speed seems a bit wasteful, so I had to upgrade to two 1GB modules and drop another $50.

I’m thankful for the advice, though, even though it’s conceivable I never would have noticed that my RAM isn’t running at full speed. I just don’t tinker with my hardware enough anymore. I just don’t have time, and I despise the people that do.

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post  

Problems With Instrumented Runtime

I’m running tests again that use a Java runtime in which synchronized blocks have been instrumented with logging calls. This is pretty much the minimum capability I need. Georges does it too.

I’m getting both a HotSpot Virtual Machine error and an exception in the JPDA thread monitor I wrote:

# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x6d728200, pid=5864, tid=5844
# V  [jvm.dll+0xe8200]

I don’t know if the two have anything to do with each other, but the exception I got in the thread monitor is due to a null reference where I’m expecting a ThreadReference. This means a synchronized block entry has been logged but Thread.currentThread() returns null. Fantastic. Again I’m finding I’m doing things too early during VM initialization.

I think it will be very hard to distinguish at instrumentation time which places cause this behavior. That means I probably have to instrument them all and decide at runtime. Now, there are two options: I can ignore the event, which is probably ok since the Java VM clearly hasn’t been set up completely yet; or I can report and special-case it, which might get hairy on the thread monitor side.

Update

I’ve started to go the special-case route (I’m trying to be thorough: if something can be reported, it should be — it can always be ignored later), and I’ve noticed that the HotSpot VM error only seems to occur when the JPDA thread monitor is attached. If I run the slave program without the monitor, the log functions do get called, but no error occurs. Quite peculiar.

Share
Posted in Concurrent Unit Testing | Leave a comment

Print This Post Print This Post  

Different Way of Instrumenting Object.∗

The paper I read also uses a different approach for instrumenting Object.∗. I chose to add a wrapper that logs and forwards, and then to change all calls to Object.∗ to point to Object.∗<Wrapper>.

The advantage of that is that only the bytecode size of the Object class increases. The other classes have to be touched, but it’s just a change in the reference. Unfortunately, it also means that I need to touch Java’s private parts.

Georges, et al chose to leave the Object.∗ methods unchanged and then add the logging calls at every call site. That increases the bytecode size of all classes, but it might be easier to do.

I’ll give it a shot.

Share
Posted in Concurrent Unit Testing | Leave a comment

Print This Post Print This Post  

Instrumenting Synchronized Methods Locally

I’ve described already why instrumenting synchronized methods is an instrumentation with global effects: We need a “try to enter” logging call before the lock is claimed, and Java synchronized methods automatically do that, so the logging call needs to happen at the call site before the call is made.

Corky, my advisor, pointed towards an interesting 2004 paper on JaRec by Georges, et al. The implementation shares many aspect with the approach we are following and I’ll have to study it more closely, but one interesting idea I could glean from it already was a way to make instrumenting synchronized methods have only local effect:

A synchronized method

synchronized T foo(T0 t0, T1 t1, ...) {
S
}

is transformed into an unsynchronized method and a synchronized block, which can then later be instrumented in the usual manner:

T foo(T0 t0, T1 t1, ...) {
synchronized(this) {
S
}
}

For a static synchronized method, instead of this‘s lock, the lock of the class object is claimed. On a Java bytecode level, case has to be taken that the lock is released properly in case of exceptions, since this now has to be handled manually.

I don’t know why I didn’t test this way myself in the first place. I can only assume I wasn’t sure about the precise semantics of synchronized methods at the time. Also, this scheme won’t work for synchronized native methods. They will still have to be handled with the wrapper approach, incurring global effects.

This is nonetheless a very interesting approach that I will have to inspect. On the one hand, it reduces the absolute number of changes that have to be made (by making the instrumentation have only local effects), on the other hand, it changes the number of ways in which class files need to be changed (by transforming synchronized methods to the canonical case of a synchronized block).

Unfortunately, the test I just ran showed me I still have problems instrumenting classes deep inside the runtime.

Share
Posted in Concurrent Unit Testing | Leave a comment

Print This Post Print This Post  

New PC…

So… Despite AMD price cuts looming on the horizon, I’ve just placed an order for the PC described earlier. The allergic reactions to my current computer being so slow just became too hard to handle. The $858.32 I spent will be sorely missed, but I hope everything will get better with the new computer. Just switching between programs took seconds, scrolling wasn’t smooth anymore, and often I could type faster than the computer would display the characters.

I really don’t know why that is. It seems like the performance of my PC has deteriorated a lot just over the last few weeks. I’m sure it’s not a virus, and my Windows installation is relatively new — only a year old. The only factors of change, as far as I can see, are IDEA and the size of my projects.

My productivity has definitely suffered under the speed and stability problems. With large projects, I more and more rely on fast searches and auto-completion to maintain a clear picture of what is going on, and that just wasn’t possible anymore.

I hope the new PC is ready for pick-up before the end of the week so I can install everything over the weekend and get working again. Until then… I’ll try to do the best I can :-S

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post  

Types of instrumentation

In general, the instrumentations I’m doing can be grouped into two categories: Those that only require local modification of a class file, and those that require changes to all the other class files that use it as well.

Instrumentations with Local Effects

The first case is a lot easier to handle. Instrumenting Thread.* (except for sleep and yield) and instrumenting synchronized blocks belongs here. As mentioned already, in the former case I just rename the old method and substitute a new method that logs and forwards. Because this method has the same name, the classes that use the method will never know anything changed. In the latter case, I just insert log calls before and after the MONITORENTER and before the MONITOREXIT opcodes. This only affects the code locally.

Instrumentations with Global Effects

Unfortunately, there are other events that need to be monitored. Object.*, Thread.sleep and Thread.yield, for example, are native methods and cannot be renamed. For these methods, I introduce an additonal wrapper method that does the logging and forwarding. Then I need to scan through all other files and make calls to the original method point to the wrapper method.

Synchronized methods automatically claim a lock, there’s no opcode that I can look for, so the “trying to enter” event must actually be handled at the call site, as opposed to inside the method. That means I need to go through all files and insert “trying to enter” log calls before calls to synchronized methods. That, of course, also means that I have to know what methods are synchronized in the first place.

In synchronized native methods, I can’t insert the “entered” log call, so I need to follow a wrapper approach, just like with the Object.* methods.

Results

The upshot of instrumentation with global effects is that you cannot perform all instrumentations on just a few classes in isolation. If you instrument Object.*, Thread.sleep, Thread.yield, or synchronized methods in one class, you have to make corresponding changes in all classes that use it.

Since I’ve run into trouble instrumenting the entire Java runtime, we’ve been considering not instrumenting all portions of it and maybe leaving large portions of java.lang.* uninstrumented. Of course, the Thread and Object classes have to be instrumented, but others could be left out.

With global effects, though, an arbitrarily partial instrumentation might not be possible. It seems like we need to instrument at least something akin to the smallest transitive closure of classes. Fortunately, the way I have global-effect instrumentations set up right now, a program should work even if it is not instrumented correctly. An uninstrumented class would just call the original method, not the wrapper. The program couldn’t be monitored correctly, but it would at least work.

That doesn’t seem like a very helpful thing, since we really need complete information about all the events, but depending on the semantic model we use, it might save the day: If we assume that certain portions of the runtime are thread-safe, then we can safely lose some or all synchronization information about that portion.

Share
Posted in Concurrent Unit Testing | Leave a comment

Print This Post Print This Post  

AMD Price Cuts in July

I just heard rumors about AMD price cuts in July. I was ready to put in an order for a new PC this week, but maybe I’ll wait another month now.

Oh. And I’m 25.5 years old today. Does anybody want to chip in and buy me that PC as a present?

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post  

Distinguishing between user and system classes

Earlier I was wondering how to distinguish between classes I needed to instrument and those that are in the runtime and thus assumed to have been instrumented correctly already. This is easier than I thought: If a file cannot be loaded through some other means, there is a special method findSystemClass to load system classes. I’ll only instrument classes loaded through other means, e.g. directly from a class file. A “do not instrument” annotation might still be useful, though.

Share
Posted in Concurrent Unit Testing | Leave a comment

Print This Post Print This Post  

Next up

I’ve already mentioned that the JPDA monitor reads and clears a list mainainted in the slave. Reading isn’t the problem, but clearing is a bit tricky. If the monitor just had to read, then hardly any synchronization were necessary (well, I’d have to write my own version of ArrayList. I looked at its source and noticed that ArrayList increments the size first, then puts the entry in. It would be cleaner the other way around).

The monitor needs to clear the list too, though, and that is a write access. This is a recipe for a race condition. If the monitor clears the list after the slave has determined where it needs to put the new event but before the slave has actually put the event into the list, the slave will experience a NullPointerException (the monitor resets the list to null. I couldn’t find a way to create a new ArrayList).

It is somewhat ironic: A synchronization bug, in a program that is supposed to fight synchronization bugs.

I’ve devised two strategies to prevent this problem:

  1. Whenever the slave adds an event, it grabs a lock (using a synchronized method). The monitor can check if that lock is held by a thread and postpone checking the list until the thread has finished adding the event. This can somewhat easily be done using a “method exit event” from JPDA. The advantage is low memory use and an immediate update right when the slave is done. I’m afraid that enabling and disabling this JPDA event will be too slow.
  2. Another strategy is to just not clear the list if the lock is held. In that case, the monitor remembers how many entries in the list it has already seen. The next time around, only new events will be processed. Eventually (hopefully?), the lock will not be held, and the list can be cleared. The advantage here is no added cost, but at least theoretically, the list can grow without bound.

Of course, both methods can be combined, with 1. providing a low-memory fall-back for 2. Right now I have implemented option 1, and at least in simple tests it seems fast enough, so I’m not writing 2. yet.

However, I’d like to test this on a larger program, and that large program is DrJava, of course. To efficiently do that, I’ll need to dust off and modify the custom class loader again, so that’s what I’ll probably do next.

Running a program will mean running the monitor with the slave as a parameter. The boot classpath for the slave also has to be changed so that it includes the instrumented runtime files and several monitor classes (the SyncPointRecorder class, for example). The monitor then loads the slave, and the class loader instruments all user classes.

Since I don’t want to instrument classes again that have already been instrumented (that would wreak havoc; foo<Wrapper> methods would call themselves, etc.), I’ll have to figure out how to distinguish user classes from runtime classes, or better: instrumented classes from uninstrumented ones. Maybe I can use Java annotations for that?

Share
Posted in Concurrent Unit Testing | Leave a comment

Print This Post Print This Post  

New PC?

I’ve been agonizing about buying a new computer for the last three weeks. My current PC, a Pentium III 733 with 640Mb RAM, is almost five years old — just one month shy of it. It’s about time to buy a new one… Working with IntelliJ IDEA has become a pain. I don’t know why. Has IDEA become bigger and thus slower? Have my projects become bigger? Either way, I can’t really change any of that, I have to fight the symptoms.

The problem with buying a new PC is that I’m also saving money to buy a car. It’s hard to save for two important things at the same time. Originally, my plan was to first get the car and somehow make it with this PC until the end of the year. By now, I’m so pissed off that I think I’ll buy the PC first.

Right now, I’m thinking of getting a new case with a supposedly semi-quiet power supply, an additional quiet case fan, an Athlon 64 3500+ CPU with a quiet cooler, an Asus A8V motherboard with AGP, 2Gb RAM (4 modules), and a Western Digital 160Gb 7200 RPM SATA hard drive.

Originally, I had also thought about using a two-drive RAID 0 array, or including a 37Gb 10000 RPM SATA Raptor hard drive. I don’t think it’s really necessary, though. I even thought about cutting the 2Gb RAM to 1Gb, but I think 2Gb would be a good thing.

I did consider noise when I chose these components. For a while, I thought about using a fan-less power supply and liquid cooling, but that would have added about $250, and I’m not sure if it’s necessary. In Houston, the AC is one most of the time anyway, and that drowns out a PC completely.

So… any comments on these components? I haven’t ordered them yet, I’m still waiting for more money…

Update

I got this PC, but I ordered 2Gb RAM (2 modules) instead.

Share
Posted in Uncategorized | Leave a comment

Print This Post Print This Post