Related
Is there any maximum size for code in Java? I wrote a function with more than 10,000 lines. Actually, each line assigns a value to an array variable.
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";
And while compiling, I get this error: code too large
How do I overcome this?
A single method in a Java class may be at most 64KB of bytecode.
But you should clean this up!
Use .properties file to store this data, and load it via java.util.Properties
You can do this by placing the .properties file on your classpath, and use:
Properties properties = new Properties();
InputStream inputStream = getClass().getResourceAsStream("yourfile.properties");
properties.load(inputStream);
There is a 64K byte-code size limit on a method
Having said that, I have to agree w/Richard; why do you need a method that large? Given the example in the OP, a properties file should suffice ... or even a database if required.
According to the Java Virtual Machine specification, the code of a method must not be bigger than 65536 bytes:
The value of the code_length item gives the number of bytes in the code array for this method.
The value of code_length must be greater than zero (as the code array must not be empty) and less than 65536.
code_length defines the size of the code[] attribute which contains the actual bytecode of a method:
The code array gives the actual bytes of Java Virtual Machine code that implement the method.
This seems a bit like madness. Can you not initialize the array by reading the values from a text file, or some other data source?
This error sometimes occur due to too large code in a single function...
To solve that error, split that function in multiple functions, like
//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();
}
Try to refactor your code. There is limit on the size of method in Java.
As mentioned in other answers there is a 64KB of bytecode limit for a method (at least in Sun's java compiler)
Too me it would make more sense to break that method up into more methods - each assigning certain related stuff to the array (might make more sense to use a ArrayList to do this)
for example:
public void addArrayItems()
{
addSculptureItems(list);
...
}
public void addSculptureItems(ArrayList list)
{
list.add("sculptures");
list.add("stonesculpture");
}
Alternatively you could load the items from a static resource if they are fixed like from a properties file
I have run into this problem myself. The solution that worked for me was to refactor and shrink the method to more manageable pieces. Like you, I am dealing with a nearly 10K line method. However, with the use of static variables as well as smaller modular functions, the problem was resolved.
Seems there would be a better workaround, but using Java 8, there is none...
I came to this question because I was trying to solve a similar problem. I wanted to hard code a graph that had 1600 elements into a 2D integer array for performance reasons. I was solving a problem on a leetcode style website and loading the graph data from a file was not an option. The entire graph exceeded the 64K maximum so I could not do a single static run of assignments. I split the assignments across several static methods each below the limit and then called each method one by one.
private static int[][] G = new int[1601][];
static {
assignFirst250();
assignSecond250();
assignSecond500();
assignThird500();
}
private static void assignFirst250() {
G[1] = new int[]{3,8,15,24,35,48,63,80,99,120,143,168,195,224,255,288,323,360,399,440,483,528,575,624,675,728,783,840,899,960,1023,1088,1155,1224,1295,1368,1443,1520,1599};
G[2] = new int[]{2,7,14,23,34,47,62,79,98,119,142,167,194,223,254,287,322,359,398,439,482,527,574,623,674,727,782,839,898,959,1022,1087,1154,1223,1294,1367,1442,1519,1598};
You can add another method to create space for your code for additional data space, you might have a method that is taking a large amount of data space. Try dividing your methods because I had the same issue and and fix it by creating another an additional method for the same data in my java Android code, The issue was gone after I did that.
I have an enum that causes the .java file to be over 500KB in size. Eclipse can build it for some reason; the eclipse-exported ant build.xml cannot. I'm looking into this and will update this post.
this is due to all code in single methods
solution :create more some small methods then this error will be gone
As there is a size limit for methods and you don't want to redesign your code as this moment, may be you can split the array into 4-5 parts and then put them into different methods. At the time of reading the array, call all the methods in a series. You may maintain a counter as well to know how many indexes you have parsed.
ok maybe this answer is too late but I think this way is better than another way so
for example, we have 1000 rows data in code
break them
private void rows500() {
//you shoud write 1-500 rows here
}
private void rows1000() {
you shoud write 500-1000 rows here
}
for better performance put an "if" in your codes
if (count < 500) {
rows500();
} else if (count > 500) {
rows1000();
}
I hope this code helps you
I have a file with several hundreds of stopwords. I want to be able to check if the file has been modified by a user for example or even if it is corrupted.
The way I am thinking of doing it currently is by looking if the number of lines is correct. I could also check if the total number of characters is the one expected or even have the whole stopwords list loaded in memory to check if every single one of them is in the file. All 3 of the ways I thought of seem inefficient and/or bad so I thought of asking if there is any better way of doing it.
What I am thinking of implementing:
private static final int WORD_COUNT = 354;
public static boolean stopwordsCorrupted(File file) {
int numOfLines = countLines(file);
return WORD_COUNT != numOfLines;
}
Check out this: http://en.wikipedia.org/wiki/Checksum This uses the hashfuntion of the file to check if no alterations have been made
Here you also have an example of how to use it.
Java WatchService API might be helpful for your problem.
I saw the following code in this commit for MongoDB's Java Connection driver, and it appears at first to be a joke of some sort. What does the following code do?
if (!((_ok) ? true : (Math.random() > 0.1))) {
return res;
}
(EDIT: the code has been updated since posting this question)
After inspecting the history of that line, my main conclusion is that there has been some incompetent programming at work.
That line is gratuitously convoluted. The general form
a? true : b
for boolean a, b is equivalent to the simple
a || b
The surrounding negation and excessive parentheses convolute things further. Keeping in mind De Morgan's laws it is a trivial observation that this piece of code amounts to
if (!_ok && Math.random() <= 0.1)
return res;
The commit that originally introduced this logic had
if (_ok == true) {
_logger.log( Level.WARNING , "Server seen down: " + _addr, e );
} else if (Math.random() < 0.1) {
_logger.log( Level.WARNING , "Server seen down: " + _addr );
}
—another example of incompetent coding, but notice the reversed logic: here the event is logged if either _ok or in 10% of other cases, whereas the code in 2. returns 10% of the times and logs 90% of the times. So the later commit ruined not only clarity, but correctness itself.
I think in the code you have posted we can actually see how the author intended to transform the original if-then somehow literally into its negation required for the early return condition. But then he messed up and inserted an effective "double negative" by reversing the inequality sign.
Coding style issues aside, stochastic logging is quite a dubious practice all by itself, especially since the log entry does not document its own peculiar behavior. The intention is, obviously, reducing restatements of the same fact: that the server is currently down. The appropriate solution is to log only changes of the server state, and not each its observation, let alone a random selection of 10% such observations. Yes, that takes just a little bit more effort, so let's see some.
I can only hope that all this evidence of incompetence, accumulated from inspecting just three lines of code, does not speak fairly of the project as a whole, and that this piece of work will be cleaned up ASAP.
https://github.com/mongodb/mongo-java-driver/commit/d51b3648a8e1bf1a7b7886b7ceb343064c9e2225#commitcomment-3315694
11 hours ago by gareth-rees:
Presumably the idea is to log only about 1/10 of the server failures (and so avoid massively spamming the log), without incurring the cost of maintaining a counter or timer. (But surely maintaining a timer would be affordable?)
Add a class member initialized to negative 1:
private int logit = -1;
In the try block, make the test:
if( !ok && (logit = (logit + 1 ) % 10) == 0 ) { //log error
This always logs the first error, then every tenth subsequent error. Logical operators "short-circuit", so logit only gets incremented on an actual error.
If you want the first and tenth of all errors, regardless of the connection, make logit class static instead of a a member.
As had been noted this should be thread safe:
private synchronized int getLogit() {
return (logit = (logit + 1 ) % 10);
}
In the try block, make the test:
if( !ok && getLogit() == 0 ) { //log error
Note: I don't think throwing out 90% of the errors is a good idea.
I have seen this kind of thing before.
There was a piece of code that could answer certain 'questions' that came from another 'black box' piece of code. In the case it could not answer them, it would forward them to another piece of 'black box' code that was really slow.
So sometimes previously unseen new 'questions' would show up, and they would show up in a batch, like 100 of them in a row.
The programmer was happy with how the program was working, but he wanted some way of maybe improving the software in the future, if possible new questions were discovered.
So, the solution was to log unknown questions, but as it turned out, there were 1000's of different ones. The logs got too big, and there was no benefit of speeding these up, since they had no obvious answers. But every once in a while, a batch of questions would show up that could be answered.
Since the logs were getting too big, and the logging was getting in the way of logging the real important things he got to this solution:
Only log a random 5%, this will clean up the logs, whilst in the long run still showing what questions/answers could be added.
So, if an unknown event occurred, in a random amount of these cases, it would be logged.
I think this is similar to what you are seeing here.
I did not like this way of working, so I removed this piece of code, and just logged these
messages to a different file, so they were all present, but not clobbering the general logfile.
Is there any maximum size for code in Java? I wrote a function with more than 10,000 lines. Actually, each line assigns a value to an array variable.
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";
And while compiling, I get this error: code too large
How do I overcome this?
A single method in a Java class may be at most 64KB of bytecode.
But you should clean this up!
Use .properties file to store this data, and load it via java.util.Properties
You can do this by placing the .properties file on your classpath, and use:
Properties properties = new Properties();
InputStream inputStream = getClass().getResourceAsStream("yourfile.properties");
properties.load(inputStream);
There is a 64K byte-code size limit on a method
Having said that, I have to agree w/Richard; why do you need a method that large? Given the example in the OP, a properties file should suffice ... or even a database if required.
According to the Java Virtual Machine specification, the code of a method must not be bigger than 65536 bytes:
The value of the code_length item gives the number of bytes in the code array for this method.
The value of code_length must be greater than zero (as the code array must not be empty) and less than 65536.
code_length defines the size of the code[] attribute which contains the actual bytecode of a method:
The code array gives the actual bytes of Java Virtual Machine code that implement the method.
This seems a bit like madness. Can you not initialize the array by reading the values from a text file, or some other data source?
This error sometimes occur due to too large code in a single function...
To solve that error, split that function in multiple functions, like
//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();
}
Try to refactor your code. There is limit on the size of method in Java.
As mentioned in other answers there is a 64KB of bytecode limit for a method (at least in Sun's java compiler)
Too me it would make more sense to break that method up into more methods - each assigning certain related stuff to the array (might make more sense to use a ArrayList to do this)
for example:
public void addArrayItems()
{
addSculptureItems(list);
...
}
public void addSculptureItems(ArrayList list)
{
list.add("sculptures");
list.add("stonesculpture");
}
Alternatively you could load the items from a static resource if they are fixed like from a properties file
I have run into this problem myself. The solution that worked for me was to refactor and shrink the method to more manageable pieces. Like you, I am dealing with a nearly 10K line method. However, with the use of static variables as well as smaller modular functions, the problem was resolved.
Seems there would be a better workaround, but using Java 8, there is none...
I came to this question because I was trying to solve a similar problem. I wanted to hard code a graph that had 1600 elements into a 2D integer array for performance reasons. I was solving a problem on a leetcode style website and loading the graph data from a file was not an option. The entire graph exceeded the 64K maximum so I could not do a single static run of assignments. I split the assignments across several static methods each below the limit and then called each method one by one.
private static int[][] G = new int[1601][];
static {
assignFirst250();
assignSecond250();
assignSecond500();
assignThird500();
}
private static void assignFirst250() {
G[1] = new int[]{3,8,15,24,35,48,63,80,99,120,143,168,195,224,255,288,323,360,399,440,483,528,575,624,675,728,783,840,899,960,1023,1088,1155,1224,1295,1368,1443,1520,1599};
G[2] = new int[]{2,7,14,23,34,47,62,79,98,119,142,167,194,223,254,287,322,359,398,439,482,527,574,623,674,727,782,839,898,959,1022,1087,1154,1223,1294,1367,1442,1519,1598};
You can add another method to create space for your code for additional data space, you might have a method that is taking a large amount of data space. Try dividing your methods because I had the same issue and and fix it by creating another an additional method for the same data in my java Android code, The issue was gone after I did that.
I have an enum that causes the .java file to be over 500KB in size. Eclipse can build it for some reason; the eclipse-exported ant build.xml cannot. I'm looking into this and will update this post.
this is due to all code in single methods
solution :create more some small methods then this error will be gone
As there is a size limit for methods and you don't want to redesign your code as this moment, may be you can split the array into 4-5 parts and then put them into different methods. At the time of reading the array, call all the methods in a series. You may maintain a counter as well to know how many indexes you have parsed.
ok maybe this answer is too late but I think this way is better than another way so
for example, we have 1000 rows data in code
break them
private void rows500() {
//you shoud write 1-500 rows here
}
private void rows1000() {
you shoud write 500-1000 rows here
}
for better performance put an "if" in your codes
if (count < 500) {
rows500();
} else if (count > 500) {
rows1000();
}
I hope this code helps you
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is there a workaround for Java's poor performance on walking huge directories?
I created a utility which lists all the files within some directory by using File.listFiles() function, but the problem occurred when i copied huge amount of files (around 100K) under that directory.
I was looking for some solution take actually takes some fixed no of files (say X) from that directory and processes and then deletes those files and takes next X number of files.
Can any one please suggest me any solution.
Regards
One solution could be to use a FileNameFilter that either returns false after a certain number of files have been accepted or, if you are prepared to abuse Exceptions a little, throw an Exception at that point.
class CountedFilter implements FilenameFilter {
int limit = 0;
public CountedFilter ( int limit ) {
this.limit = limit;
}
public boolean accept(File file, String string) {
return limit-- > 0;
}
}
There is another option which is nowhere near as succinct but I believe is more effective. It involves a FilenameFilter that posts each file back to the caller through a BlockingQueue. The File.list is called in a separate thread so you don't have to wait for it to complete.
This solution has the added benefit that the files can be processed while File.list is running producing a much smoother solution, much like an iterator. If encouraged I will post the code as a separate answer.