Mengapa server saya menginisialisasi jauh lebih lambat di JUnit dibandingkan ketika dijalankan sendiri

Saya memiliki server tempat saya ingin melakukan tes fungsional otomatis. Ia perlu menginisialisasi beberapa ribu objek total untuk membangunnya dalam model memori, mengambil data dari file konfigurasi, tetapi ini masih sepele untuk komputer dan ini adalah bootup yang hampir seketika ketika dijalankan dari gerhana.

Saat saya menjalankan program yang sama sebagai bagian dari pengujian junit, fase inisialisasi memerlukan waktu sekitar 15 detik, bukan kecepatan sesaat dari aplikasi yang berdiri sendiri. Tidak terlalu lama, tapi jika saya berencana melakukan lusinan tes, itu akan bertambah.

Menurut JVisualVM kali ini tersebar di setengah lusin metode, tidak ada satu metode pun yang memakan waktu lebih lama dari 14% waktu CPU (ini setelah saya mengoptimalkan metode yang menghabiskan 50% CPU). Semua metode yang berjalan adalah metode yang saya perkirakan akan berjalan dan sepertinya memakan persentase yang wajar dari total waktu CPU; Saya tidak dapat membandingkannya dengan server langsung karena server langsung diinisialisasi dengan sangat cepat sehingga saya tidak dapat memulai dan menghentikan JVisualVM dengan cukup cepat untuk membuat profilnya. Sepertinya metode init dari semua objek saya mungkin memerlukan waktu lebih lama, misalnya satu objek menggunakan 3% cpu untuk init, tetapi memiliki waktu mandiri 000 ms dan tidak melakukan panggilan lain; tapi saya tidak tahu apakah itu hasil yang umum menggunakan JVisualVM?

Meskipun tidak masalah, saya melakukan satu hal secara berbeda di Junit vs menjalankan sebagai aplikasi yang berdiri sendiri; Saya menggunakan objek serverMock (meskipun ini bukan ATM tiruan). Itu memperluas objek server saya. Saat ini satu-satunya alasan untuk memperluasnya adalah karena metode run server (yang berjalan tanpa batas waktu menunggu pesan masuk) adalah metode terlindungi yang dipanggil oleh metode main() ketika server dijalankan sebagai jar. Tiruan saya menambahkan metode yang akan memunculkan utas untuk menjalankan metode run server karena saya tidak punya cara lain untuk memulai metode dalam pengujian unit. Namun, perlambatan terjadi pada inisialisasi server sebelum mencapai metode yang dijalankan; jadi menurut saya ini bukan penyebab perlambatan?


person dsollen    schedule 24.09.2013    source sumber
comment
Apakah Anda melengkapi kode tersebut untuk alasan cakupan, atau semacamnya?   -  person Jon Skeet    schedule 24.09.2013
comment
tidak, belum. Saya sedang menulis tes yang paling dasar saat ini. Sejauh ini saya memiliki dua tes yang tidak melakukan apa pun selain menginisialisasi server, melakukan ping, dan mematikannya. Tidak ada cakupan kode atau perilaku lain selain perilaku junit default dasar   -  person dsollen    schedule 24.09.2013
comment
Dan apakah ini berjalan di bawah debugger? (Saya tidak akrab dengan JVisualVM, tetapi jika Anda belum mencoba menjalankan tes di bawah JVM biasa, itu akan menjadi tujuan pertama Anda.)   -  person Jon Skeet    schedule 24.09.2013
comment
Apakah Anda menggunakan vmarg yang sama? Dan apakah Anda sudah mempertimbangkan untuk menggunakan Hudson/Jenkins untuk memulai tes secara otomatis saat check-in?   -  person Axel    schedule 24.09.2013
comment
Saya menjalankan JVisualVm terhadap versi kode di debugger, jadi saya hanya bisa menargetkan bagian init yang memakan waktu sangat lama. Namun, saya telah menjalankan tes di luar debugger dan bagian dari MVN build dan mendapatkan masalah yang sama di kedua tempat. Saya belum menyentuh VMArg sehingga keduanya harus sama secara default di kedua kasus?   -  person dsollen    schedule 24.09.2013
comment
Apakah lingkungan runtime (misalnya direktori kerja, vm args, Caspian, properti sistem) identik? Apakah inisialisasi server (yaitu jalur melalui aplikasi) identik ketika dijalankan di kedua lingkungan? File konfigurasi yang sama? Pencatatan yang sama?   -  person Kkkev    schedule 25.09.2013
comment
Bisakah Anda menjelaskan dengan tepat apa yang Anda maksud dengan fase inisialisasi membutuhkan waktu 15 detik. Bagaimana Anda mengatur waktunya? Peristiwa manakah yang Anda catat waktunya? Apa yang Anda lihat di layar? Apakah 15 detik sebelum tampilan runner JUnit mulai menampilkan sesuatu atau 15 detik sebelum proses dimulai atau...?   -  person Aaron Digulla    schedule 25.09.2013
comment
Saya yakin logging dan hal lainnya adalah sama; Saya belum mengubah semuanya secara eksplisit dan memastikan untuk menggunakan file konfigurasi yang sama setidaknya.   -  person dsollen    schedule 26.09.2013
comment
Saya sebenarnya memberi jeda antara panggilan yang memuat dari file konfigurasi dan membangun model memori kita dan panggilan berikutnya dalam konfigurasi. Kemudian saya menggunakan JVisualVM untuk mendapatkan jejak penggunaan CPU hanya untuk satu panggilan ini dengan menjalankannya hanya dalam waktu yang diperlukan untuk beralih dari breakpoint pertama ke kedua. Pembacaan dan pembuatan file konfigurasi ini memakan waktu sekitar 95% dari waktu booting penuh jika dilihat dari respons sistem secara umum. Tampaknya pembuatan model ini, bukan pembacaan file, yang menghabiskan waktu CPU.   -  person dsollen    schedule 26.09.2013
comment
Apakah Anda menjalankan Eclipse saat menjalankan server Anda sendiri? Eclipse mengkonsumsi sejumlah besar RAM. Mungkin saja server Anda harus bertukar saat menjalankan Eclipse dan server Anda. Tampaknya juga RAM yang dialokasikan berbeda. Bisakah Anda menambahkan beberapa pernyataan debug setelah inisialisasi untuk mencetak jumlah total GC yang telah dijalankan dan% waktu yang dihabiskan untuk GC? Pertanyaan ini menjelaskan caranya.   -  person Pace    schedule 26.09.2013
comment
Saya menggunakan gerhana untuk menjalankan kedua versi, hanya satu yang saya lakukan junit, yang satu saya lakukan di server sendiri. Saya akan mencoba saran lainnya.   -  person dsollen    schedule 26.09.2013