I write a lot of hand-optimized Java code, and have found that while Java as a language can be pretty fast, and its HotSpot team is to be commended, Sun's libraries are often atrocious. For example, until Java 1.5 (I think, maybe 1.4) ArrayList's get(), set(), and add() methods were not inline-able, and a one-line fix to the problem languished for years on Sun's bug forums. Sun's decision to go with type erasure was also a huge mistake in my opinion: as a result we have hilariously inefficient boxing and unboxing operations in poorly written Java code. Sun's push towards iterators hasn't helped things either.
If you eschew all this and write strongly optimized code, I think the single biggest spot where Java is unquestionably slower than C/C++ is in array accesses. In Java, to set a slot in a two-dimensional array Java must first test to see if the array is non-null, then test that the X bounds are correct, then test to see if the appropriate Y subarray is non-null, then test to see if the Y bounds are correct, then finally set the value.
In C the compiler does a multiply and an add and sets the slot.