Moi-même et un autre développeur sur mon temps récemment déplacé d'une machine Core 2 Duo au travail à un nouveau Core 2 Quad 9505; les deux exécutant Windows XP SP3 32 bits avec JDK 1.6.0_18. Ce faisant, un couple de nos tests unitaires automatisés pour un code d'agrégation de synchronisation/statistiques/métriques a rapidement commencé à échouer, en raison de ce qui semble être des valeurs ridicules revenant de System.nanoTime().Pourquoi mon System.nanoTime() est-il cassé?
Code d'essai qui montre ce comportement, de manière fiable, sur ma machine est:
import static org.junit.Assert.assertThat;
import org.hamcrest.Matchers;
import org.junit.Test;
public class NanoTest {
@Test
public void testNanoTime() throws InterruptedException {
final long sleepMillis = 5000;
long nanosBefore = System.nanoTime();
long millisBefore = System.currentTimeMillis();
Thread.sleep(sleepMillis);
long nanosTaken = System.nanoTime() - nanosBefore;
long millisTaken = System.currentTimeMillis() - millisBefore;
System.out.println("nanosTaken="+nanosTaken);
System.out.println("millisTaken="+millisTaken);
// Check it slept within 10% of requested time
assertThat((double)millisTaken, Matchers.closeTo(sleepMillis, sleepMillis * 0.1));
assertThat((double)nanosTaken, Matchers.closeTo(sleepMillis * 1000000, sleepMillis * 1000000 * 0.1));
}
}
sortie typique:
millisTaken=5001
nanosTaken=2243785148
Son exécution donne 100x nano résultats entre 33% et 60% du réel Temps de sommeil; habituellement autour de 40% cependant. Je comprends les faiblesses dans la précision des minuteurs dans Windows, et ai lu des threads apparentés comme Is System.nanoTime() consistent across threads?, cependant je crois comprendre que System.nanoTime() est exactement dans le but pour lequel nous l'utilisons: - mesurer le temps écoulé; plus précisément que currentTimeMillis().
Est-ce que quelqu'un sait pourquoi il rend des résultats aussi fous? Est-ce que cela risque d'être un problème d'architecture matérielle (la seule chose qui a changé est la CPU/carte mère sur cette machine)? Un problème avec Windows HAL avec mon matériel actuel? Un problème JDK? Dois-je abandonner nanoTime()? Dois-je enregistrer un bug quelque part, ou des suggestions sur la façon dont je pourrais enquêter plus loin?
MISE À JOUR 19/07 03:15 UTC: Après avoir essayé le cas de test de finnw ci-dessous je l'ai fait un peu plus googler, à venir à travers des entrées telles que bugid:6440250. Cela m'a aussi rappelé un autre comportement étrange que j'ai remarqué vendredi soir où les pings revenaient négatifs. J'ai donc ajouté /usepmtimer à mon boot.ini et maintenant tous les tests se comportent comme prévu., Et mes pings sont normaux aussi.
Je suis un peu confus au sujet de pourquoi c'était toujours un problème si; D'après mes lectures, je pensais que les problèmes TSC vs PMT étaient largement résolus dans Windows XP SP3. Serait-ce parce que ma machine était à l'origine SP2, et a été corrigé au SP3 plutôt qu'installé à l'origine en tant que SP3? Je me demande maintenant si je devrais installer des correctifs comme celui au MS KB896256. Peut-être que je devrais prendre cela avec l'équipe de création de bureau de l'entreprise?
Avez-vous acheté une machine complètement neuve ou votre machine actuelle a-t-elle été mise à niveau en conservant l'ancienne installation de Windows? –
Entièrement nouvelle machine; reconstruit sur une construction standard d'entreprise. – Chad
fonctionne bien pour moi sous Windows 7 64 bits dernière JDK 6. – TofuBeer