Kesalahan kompilasi "Kode terlalu besar" di Java


94

Apakah ada ukuran maksimum untuk kode di Java? Saya menulis fungsi dengan lebih dari 10.000 baris. Sebenarnya, setiap baris memberikan nilai ke variabel array.

arts_bag[10792]="newyorkartworld";
arts_bag[10793]="leningradschool";
arts_bag[10794]="mailart";
arts_bag[10795]="artspan";
arts_bag[10796]="watercolor";
arts_bag[10797]="sculptures";
arts_bag[10798]="stonesculpture"; 

Dan saat kompilasi, saya mendapatkan kesalahan ini: kode terlalu besar

Bagaimana cara mengatasinya?


9
Aku hanya terpana ... Pasti ada cara yang lebih baik untuk melakukan ini.
Thanos Papathanasiou

7
Anda benar-benar perlu melihat database untuk jenis hal ini, gagal file properti itu.
Paul Whelan

45
Mengapa kalian meneriaki pria malang itu karena desain yang buruk? Mungkin OP memperoleh metode gila itu dengan beberapa alat pembuat kode.
webuster

15
Saya terkejut bahwa komentar kritis yang dangkal ini mendapat begitu banyak suara positif!
Evgeni Sergeev

7
Mengapa startup aplikasi Anda menghabiskan banyak waktu dengan mem-parsing beberapa file teks padahal Anda dapat meminta compiler untuk menghasilkan semuanya pada saat kompilasi? Ini adalah desain yang buruk jika Anda ingin mengubah data tanpa mengompilasi ulang, atau menulis metode secara manual, tetapi itu bukan desain yang buruk jika Anda membuat kode sumber. (Setidaknya jika Anda melakukannya dengan cara yang benar-benar memungkinkan compiler untuk membuat array sebelumnya).
Guntram Blohm

Jawaban:


93

Satu metode dalam kelas Java mungkin memiliki bytecode paling banyak 64 KB.

Tapi Anda harus membersihkannya!

Gunakan .propertiesfile untuk menyimpan data ini, dan muat melaluijava.util.Properties

Anda dapat melakukan ini dengan menempatkan .propertiesfile di classpath Anda, dan menggunakan:

Properties properties = new Properties();
InputStream inputStream = getClass().getResourceAsStream("yourfile.properties");
properties.load(inputStream);

2
"Tidak peduli berapa ukuran sebenarnya untuk JDK / JVM Anda"? Apakah Anda menyiratkan bahwa batas ini tidak tetap? Karena sudah diperbaiki dan dibutuhkan oleh spesifikasi format file kelas.
Joachim Sauer

1
di mana saya dapat menemukan file .properties
trinity

1
Anda membuatnya sendiri lalu meletakkannya di jalur kelas
Markus

3
saya tidak menggunakan saran Anda, meskipun saya ingin mencobanya lain kali .. sekarang telah menggunakan database untuk menyimpan informasi ini, dan telah memodifikasi kode lainnya yang sesuai ..
trinity

1
Maaf jika ini pertanyaan bodoh, tapi .. Di mana file .properties ini harus diletakkan? Maksud saya, oke, itu ada di classpath, tapi di mana itu?
Milack27

14

Ada batas ukuran kode 64K byte pada sebuah metode

Karena itu, saya harus setuju dengan Richard; mengapa Anda membutuhkan metode sebesar itu? Diberikan contoh di OP, file properti harus cukup ... atau bahkan database jika diperlukan.


4
bagaimana dengan enum? saya mendapatkan masalah yang sama dengan set enum yang besar
Toby

1
@Toby: Saya sendiri tidak pernah menghadapi masalah ini dengan enum. Ada posting oleh pengguna lain di sini di SO tentang masalah yang sama. Misalnya - stackoverflow.com/questions/2546470 Mungkin bermanfaat untuk melihat file .class yang dihasilkan enumuntuk dilihat
Semua orang

Instance enum (yaitu objek yang mewakili konstanta) dibuat di penginisialisasi statis kelas, yang merupakan metode dan memiliki batasan yang sama.
juancn

Saya menghadapi masalah yang sama dengan kode yang dihasilkan kerangka kerja untuk formulir web yang sangat kompleks. Solusinya adalah dengan membagi formulir menjadi beberapa komponen, sehingga kode yang dihasilkan untuk setiap komponen juga dipisahkan.
SebaGra

13

Menurut spesifikasi Java Virtual Machine , kode metode tidak boleh lebih besar dari 65536 byte :

Nilai code_lengthitem memberikan jumlah byte dalam codearray untuk metode ini.

Nilai panjang_kode harus lebih besar dari nol (karena larik kode tidak boleh kosong) dan kurang dari 65536.

code_lengthmendefinisikan ukuran code[]atribut yang berisi bytecode sebenarnya dari suatu metode:

The codeArray memberikan byte sebenarnya Java kode Virtual Machine yang menerapkan metode ini.


7

Ini sepertinya agak gila. Bisakah Anda tidak menginisialisasi array dengan membaca nilai dari file teks, atau sumber data lainnya?


3
(Tidak dipilih karena) Ini membutuhkan setidaknya satu alasan mengapa teknik seperti itu buruk. Tidak mudah untuk menemukan alasan yang bagus.
Evgeni Sergeev

3

Kesalahan ini terkadang terjadi karena kode yang terlalu besar dalam satu fungsi ... Untuk mengatasi kesalahan tersebut, bagi fungsi itu menjadi beberapa fungsi, seperti

//Too large code function
private void mySingleFunction(){
.
.
2000 lines of code
}
//To solve the problem
private void mySingleFunction_1(){
.
.
500 lines of code
}
private void mySingleFunction_2(){
.
.
500 lines of code
}
private void mySingleFunction_3(){
.
.
500 lines of code
}
private void mySingleFunction_4(){
.
.
500 lines of code
}
private void MySingleFunction(){
mySingleFunction_1();
mySingleFunction_2();
mySingleFunction_3();
mySingleFunction_4();
}

2

Cobalah untuk mengubah kode Anda. Ada batasan ukuran metode di Jawa.


1
refactoring tidak jahitan sebagai ide yang masuk akal jika semua yang dia lakukan dalam metode itu adalah inisialisasi array.
Gabriel Ščerbák

2
Dia mengatakan bahwa sisa kodenya bergantung pada array ini. Jadi dia bisa merefaktor metode untuk meneruskan tanggung jawab memuat data ke beberapa metode / Pabrik lain dari file / database.
Padmarag

Anda dapat membuat dan menginisialisasi array besar tanpa menggunakan omong kosong semacam ini; lihat jawaban @ Kris.
Stephen C

Refactor - "Proses mengubah kode sumber program komputer tanpa mengubah perilaku fungsional eksternalnya untuk meningkatkan beberapa atribut nonfungsional perangkat lunak." Bagaimana jawaban lain berbeda dari ini?
Padmarag

2

Seperti yang disebutkan dalam jawaban lain, ada 64KB batas bytecode untuk sebuah metode (setidaknya dalam kompiler java Sun)

Bagi saya, akan lebih masuk akal untuk memecah metode itu menjadi lebih banyak metode - masing-masing menugaskan hal-hal terkait tertentu ke array (mungkin lebih masuk akal untuk menggunakan ArrayList untuk melakukan ini)

sebagai contoh:

public void addArrayItems()
{
  addSculptureItems(list);
  ...
}

public void addSculptureItems(ArrayList list)
{
  list.add("sculptures");
  list.add("stonesculpture");
}

Alternatifnya, Anda dapat memuat item dari sumber daya statis jika item tersebut diperbaiki seperti dari file properti


Jawaban yang benar adalah memperlakukan data sebagai data dan kode sebagai kode.
Malcolm

@Malcolm Nah, ini jelas data, dan bukan kode. Komentar Anda menyesatkan, karena yang tidak boleh Anda lakukan adalah mencampur data dan kode, tetapi di sini mereka tidak tercampur.
Evgeni Sergeev

Saya pikir ini adalah solusi yang baik. Saya menemukan masalah ini dengan sekitar 21k baris kode dengan 7000 pesan rute di dalamnya. Saya memperbaikinya dengan membagi pesan rute tersebut menjadi 7 fungsi dengan nama xxx0 xxx1 xxx2.
Pria perunggu

2

Saya sendiri mengalami masalah ini. Solusi yang berhasil bagi saya adalah memfaktor ulang dan mengecilkan metode menjadi bagian yang lebih mudah diatur. Seperti Anda, saya berurusan dengan metode garis hampir 10K. Namun, dengan penggunaan variabel statis serta fungsi modular yang lebih kecil, masalah telah teratasi.

Sepertinya akan ada solusi yang lebih baik, tetapi menggunakan Java 8, tidak ada ...


1

Anda dapat menambahkan metode lain untuk membuat ruang bagi kode Anda untuk ruang data tambahan, Anda mungkin memiliki metode yang menghabiskan banyak ruang data. Coba bagi metode Anda karena saya memiliki masalah yang sama dan dan perbaiki dengan membuat metode tambahan lain untuk data yang sama dalam kode Java Android saya, Masalahnya hilang setelah saya melakukan itu.


Ini lebih merupakan komentar daripada jawaban.
pengguna3071284

0

Saya memiliki enum yang menyebabkan file .java berukuran lebih dari 500KB. Eclipse dapat membuatnya karena beberapa alasan; build.xml semut yang diekspor gerhana tidak bisa. Saya sedang memeriksa ini dan akan memperbarui posting ini.


0

Karena ada batasan ukuran untuk metode dan Anda tidak ingin mendesain ulang kode Anda saat ini, mungkin Anda dapat membagi array menjadi 4-5 bagian dan kemudian memasukkannya ke dalam metode yang berbeda. Pada saat membaca larik, panggil semua metode dalam satu rangkaian. Anda juga dapat mempertahankan penghitung untuk mengetahui berapa banyak indeks yang telah Anda parse.


0

ini karena semua kode dalam solusi metode tunggal: buat lebih beberapa metode kecil maka kesalahan ini akan hilang


0

ok mungkin jawaban ini sudah terlambat tapi menurut saya cara ini lebih baik dari cara lain gitu

misalnya, kami memiliki 1000 data baris dalam kode

  1. Hancurkan mereka

    private void rows500() {
         //you shoud write 1-500 rows here
    }
    
    private void rows1000() {
         you shoud write 500-1000 rows here
    }
    
  2. untuk kinerja yang lebih baik, masukkan "jika" dalam kode Anda

    if (count < 500) {
        rows500();
    } else if (count > 500) {
        rows1000();
    }
    

Saya harap kode ini membantu Anda

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.