Error de compilación "Código demasiado grande" en Java

94

¿Existe algún tamaño máximo para el código en Java? Escribí una función con más de 10,000 líneas. En realidad, cada línea asigna un valor a una variable de matriz.

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"; 

Y mientras compilo, aparece este error: código demasiado grande

¿Cómo puedo superar esto?

trinidad
fuente
9
Estoy aturdido ... Seguramente habrá una mejor manera de hacer esto.
Thanos Papathanasiou
6
Realmente necesita buscar en una base de datos para este tipo de cosas, en su defecto un archivo de propiedades.
Paul Whelan
44
¿Por qué le gritan al pobre chico por un mal diseño? Quizás OP obtuvo ese método loco por alguna herramienta de generación de código.
webuster
14
¡Me sorprende que estos comentarios críticos superficiales hayan recibido tantos votos a favor!
Evgeni Sergeev
7
¿Por qué el inicio de su aplicación dedica mucho tiempo analizando algún archivo de texto cuando puede hacer que el compilador genere previamente todo en tiempo de compilación? Este es un mal diseño si desea cambiar los datos sin volver a compilar, o escribir el método manualmente, pero no es un mal diseño si genera el código fuente. (Al menos si lo hace de una manera que realmente permita al compilador pregenerar la matriz).
Guntram Blohm apoya a Monica el

Respuestas:

92

Un solo método en una clase Java puede tener como máximo 64 KB de código de bytes.

¡Pero deberías limpiar esto!

Utilice el .propertiesarchivo para almacenar estos datos y cárguelo mediantejava.util.Properties

Puede hacer esto colocando el .propertiesarchivo en su classpath y usar:

Properties properties = new Properties();
InputStream inputStream = getClass().getResourceAsStream("yourfile.properties");
properties.load(inputStream);
Bozho
fuente
2
"No importa cuál sea el tamaño real de su JDK / JVM"? ¿Está insinuando que este límite no es fijo? Porque es fijo y requerido por la especificación de formato de archivo de clase.
Joachim Sauer
1
¿Dónde puedo encontrar el archivo .properties
trinity
1
usted crea el suyo y luego lo pone en el classpath
Mark
3
No utilicé tu sugerencia, aunque estoy ansioso por probarla la próxima vez ... ahora he usado una base de datos para almacenar esta información y he modificado el resto del código en consecuencia ...
trinity
1
Lo siento si esta es una pregunta estúpida, pero ... ¿Dónde debería colocarse este archivo .properties? Quiero decir, está bien, está en el classpath, pero ¿dónde está?
Milack27
14

Hay un límite de tamaño de código de bytes de 64 K en un método

Habiendo dicho eso, tengo que estar de acuerdo con Richard; ¿Por qué necesitas un método tan grande? Dado el ejemplo en el OP, un archivo de propiedades debería ser suficiente ... o incluso una base de datos si es necesario.

Todo el mundo
fuente
4
¿qué hay de las enumeraciones? obtengo el mismo problema con grandes conjuntos de enumeraciones
Toby
1
@Toby: Nunca enfrenté este problema con la enumeración. Sin embargo, hay publicaciones de otros usuarios aquí en SO sobre el mismo problema. Por ejemplo, stackoverflow.com/questions/2546470 Puede que valga la pena mirar el archivo .class generado enumpara verlo
Todos
Las instancias de enumeración (es decir, los objetos que representan las constantes) se crean en el inicializador estático de la clase, que es un método y tiene la misma limitación.
Juan
Enfrenté el mismo problema con el código generado por el marco para un formulario web realmente complejo. La solución fue dividir el formulario en componentes, por lo que el código generado para cada componente también se dividió.
SebaGra
12

De acuerdo con la especificación de Java Virtual Machine , el código de un método no debe ser mayor de 65536 bytes. :

El valor de la code_length elemento da el número de bytes en elcode matriz para este método.

El valor de code_length debe ser mayor que cero (ya que la matriz de código no debe estar vacía) y menor que 65536.

code_lengthdefine el tamaño del code[]atributo que contiene el código de bytes real de un método:

La codematriz proporciona los bytes reales del código de la máquina virtual Java que implementa el método.

Joachim Sauer
fuente
7

Esto parece un poco una locura. ¿No puede inicializar la matriz leyendo los valores de un archivo de texto o alguna otra fuente de datos?

RichardOD
fuente
3
(Votado en contra porque) Esto necesita al menos una razón por la que tal técnica es mala. No es fácil encontrar una buena razón.
Evgeni Sergeev
2

Intente refactorizar su código. Existe un límite en el tamaño del método en Java.

Padmarag
fuente
1
la refactorización no parece una idea razonable si todo lo que hace en ese método es la inicialización de la matriz.
Gabriel Ščerbák
2
Dijo que el resto de su código depende de que sea una matriz. Entonces podría refactorizar el método para pasar la responsabilidad de cargar datos a algún otro método / Fábrica desde archivo / base de datos.
Padmarag
puede crear e inicializar matrices grandes sin recurrir a este tipo de tonterías; vea la respuesta de @Kris.
Stephen C
Refactor - "Proceso de cambiar el código fuente de un programa de computadora sin modificar su comportamiento funcional externo para mejorar algunos de los atributos no funcionales del software". ¿En qué se diferencian otras respuestas de esta?
Padmarag
2

Como se mencionó en otras respuestas, hay un límite de código de bytes de 64 KB para un método (al menos en el compilador java de Sun)

Para mí también tendría más sentido dividir ese método en más métodos, cada uno asignando ciertas cosas relacionadas a la matriz (podría tener más sentido usar una ArrayList para hacer esto)

por ejemplo:

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

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

Alternativamente, puede cargar los elementos desde un recurso estático si están arreglados como desde un archivo de propiedades

saret
fuente
La respuesta correcta es tratar los datos como datos y el código como código.
Malcolm
@Malcolm Bueno, esto es claramente datos, no código. Su comentario es engañoso, porque lo que no debe hacer es mezclar datos y código, pero aquí no se mezclan.
Evgeni Sergeev
Creo que esta es una buena solución. Me cruzo con este problema con aproximadamente 21k líneas de código con 7000 mensajes de ruta en él. Lo soluciono div esos mensajes de ruta en la función 7 con el nombre xxx0 xxx1 xxx2.
hombre de bronce
2

Yo mismo me he encontrado con este problema. La solución que funcionó para mí fue refactorizar y reducir el método a piezas más manejables. Como usted, estoy tratando con un método de casi 10K líneas. Sin embargo, con el uso de variables estáticas y funciones modulares más pequeñas, el problema se resolvió.

Parece que habría una solución mejor, pero al usar Java 8, no hay ninguna ...

Azadi B.
fuente
2

Este error a veces ocurre debido a un código demasiado grande en una sola función ... Para resolver ese error, divida esa función en varias funciones, como

//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();
}
DevLoverUmar
fuente
1

Puede agregar otro método para crear espacio para su código para espacio de datos adicional, es posible que tenga un método que esté ocupando una gran cantidad de espacio de datos. Intente dividir sus métodos porque tuve el mismo problema y corríjalo creando otro método adicional para los mismos datos en mi código Java de Android. El problema desapareció después de que hice eso.

FermDroi
fuente
Esto es más un comentario que una respuesta.
user3071284
0

Tengo una enumeración que hace que el archivo .java tenga un tamaño superior a 500 KB. Eclipse puede construirlo por alguna razón; el archivo ant build.xml exportado por eclipse no puede. Estoy investigando esto y actualizaré esta publicación.

Richard Jessop
fuente
0

Como hay un límite de tamaño para los métodos y no desea rediseñar su código en este momento, puede ser que pueda dividir la matriz en 4-5 partes y luego ponerlas en diferentes métodos. En el momento de leer la matriz, llame a todos los métodos de una serie. También puede mantener un contador para saber cuántos índices ha analizado.

Vikram Bhardwaj
fuente
0

esto se debe a todo el código en la solución de métodos únicos: cree más algunos métodos pequeños, entonces este error desaparecerá

jaigish
fuente
0

ok, tal vez esta respuesta sea demasiado tarde, pero creo que esta forma es mejor que otra, así que

por ejemplo, tenemos 1000 filas de datos en código

  1. romperlos

    private void rows500() {
         //you shoud write 1-500 rows here
    }
    
    private void rows1000() {
         you shoud write 500-1000 rows here
    }
  2. para un mejor rendimiento, ponga un "si" en sus códigos

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

Espero que este código te ayude

RahimpoorDesarrollador
fuente