You should be running these tests in separate methods as the optimisation of the first loop can interfere with the optimisation of the second i.e. the second one can be slower, just because it is second.

I suggest you run both tests at least 10 (or for 2 seconds) and use System.nanoTime() which has higher resolution.

If you do this and you still run out of memory I suggest you increase the maximum memory size. If you are running 32-bit windows, the default is very low. You can increase it with -Xmx1g on the command line


If you run the following, you can see that GCs have the biggest impact which is not surprising as the problem most produces garbage

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class Collectionss {

    public static final int TO_ADD = 10000000;

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            long timeAL = timeAddToArrayList();
            long timeLL = timeAddsToLinkedList();
            System.out.printf("Time to add %,d Integer to ArrayList %.3f sec, LinkedList %.3f%n",
                    TO_ADD, timeAL / 1e9, timeLL / 1e9);
        }
    }

    private static long timeAddToArrayList() {
        long starttime = System.nanoTime();
        List<Integer> l1 = new ArrayList<Integer>();
        for (int i = 1; i <= TO_ADD; i++) {
            l1.add(i);
        }
        assert TO_ADD == l1.size();

        return System.nanoTime() - starttime;
    }

    private static long timeAddsToLinkedList() {
        long starttime = System.nanoTime();
        List<Integer> l2 = new LinkedList<Integer>();
        for (int i = 1; i <= TO_ADD; i++) {
            l2.add(i);
        }
        assert TO_ADD == l2.size();

        return System.nanoTime() - starttime;
    }
}

prints

Time to add 10,000,000 Integer to ArrayList 0.238 sec, LinkedList 1.326
Time to add 10,000,000 Integer to ArrayList 1.193 sec, LinkedList 0.971
Time to add 10,000,000 Integer to ArrayList 0.841 sec, LinkedList 0.048
Time to add 10,000,000 Integer to ArrayList 0.349 sec, LinkedList 1.128
Time to add 10,000,000 Integer to ArrayList 0.064 sec, LinkedList 0.048

However add System.gc() before each test and you get

Time to add 10,000,000 Integer to ArrayList 0.241 sec, LinkedList 2.130
Time to add 10,000,000 Integer to ArrayList 0.070 sec, LinkedList 0.072
Time to add 10,000,000 Integer to ArrayList 0.067 sec, LinkedList 0.053
Time to add 10,000,000 Integer to ArrayList 0.069 sec, LinkedList 0.048
Time to add 10,000,000 Integer to ArrayList 0.065 sec, LinkedList 0.051
Answer from Peter Lawrey on Stack Overflow
🌐
Coderanch
coderanch.com › t › 614644 › java › Arraylist-heapsize-memory-error
Arraylist vs heapsize: Out of memory error (Performance forum at Coderanch)
And this is where the penalty is - if I've expected a list to contain 10,000 elements when I've coded it, but then reorganized the data into 200 lists of 50 elements each and forgot to change the initial capacity guess, I'm now wasting some 1,900,000 object references (about 8 MB in 32 bit JVM)!. And unlike the first case, this memory is allocated for the lifetime of the entire ArrayList (or until trimToSize() is called), whereas in the first case most of the memory allocated in excess is immediately freed.
Top answer
1 of 6
6

You should be running these tests in separate methods as the optimisation of the first loop can interfere with the optimisation of the second i.e. the second one can be slower, just because it is second.

I suggest you run both tests at least 10 (or for 2 seconds) and use System.nanoTime() which has higher resolution.

If you do this and you still run out of memory I suggest you increase the maximum memory size. If you are running 32-bit windows, the default is very low. You can increase it with -Xmx1g on the command line


If you run the following, you can see that GCs have the biggest impact which is not surprising as the problem most produces garbage

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class Collectionss {

    public static final int TO_ADD = 10000000;

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            long timeAL = timeAddToArrayList();
            long timeLL = timeAddsToLinkedList();
            System.out.printf("Time to add %,d Integer to ArrayList %.3f sec, LinkedList %.3f%n",
                    TO_ADD, timeAL / 1e9, timeLL / 1e9);
        }
    }

    private static long timeAddToArrayList() {
        long starttime = System.nanoTime();
        List<Integer> l1 = new ArrayList<Integer>();
        for (int i = 1; i <= TO_ADD; i++) {
            l1.add(i);
        }
        assert TO_ADD == l1.size();

        return System.nanoTime() - starttime;
    }

    private static long timeAddsToLinkedList() {
        long starttime = System.nanoTime();
        List<Integer> l2 = new LinkedList<Integer>();
        for (int i = 1; i <= TO_ADD; i++) {
            l2.add(i);
        }
        assert TO_ADD == l2.size();

        return System.nanoTime() - starttime;
    }
}

prints

Time to add 10,000,000 Integer to ArrayList 0.238 sec, LinkedList 1.326
Time to add 10,000,000 Integer to ArrayList 1.193 sec, LinkedList 0.971
Time to add 10,000,000 Integer to ArrayList 0.841 sec, LinkedList 0.048
Time to add 10,000,000 Integer to ArrayList 0.349 sec, LinkedList 1.128
Time to add 10,000,000 Integer to ArrayList 0.064 sec, LinkedList 0.048

However add System.gc() before each test and you get

Time to add 10,000,000 Integer to ArrayList 0.241 sec, LinkedList 2.130
Time to add 10,000,000 Integer to ArrayList 0.070 sec, LinkedList 0.072
Time to add 10,000,000 Integer to ArrayList 0.067 sec, LinkedList 0.053
Time to add 10,000,000 Integer to ArrayList 0.069 sec, LinkedList 0.048
Time to add 10,000,000 Integer to ArrayList 0.065 sec, LinkedList 0.051
2 of 6
4

If you are dealing with large data sets, then its always better to initialise your ArrayList with the correct size, in your case.

List<Integer> l1 = new ArrayList<Integer>(10000000);, otherwise your ArrayList will be having a default size of 10, and every time once the size is exceeded, the add method will create a new array of increased size copying all the contents of the old array inside your arraylist.

See the source below from ArrayList ensureCapacity method.

if (minCapacity > oldCapacity) {
    Object oldData[] = elementData;
    int newCapacity = (oldCapacity * 3)/2 + 1;
        if (newCapacity < minCapacity)
    newCapacity = minCapacity;
        // minCapacity is usually close to size, so this is a win:
        **elementData = Arrays.copyOf(elementData, newCapacity);**
}

And if its still happens, even after initialising then increase your heap size as others suggested in the post.

Discussions

arrays - ArrayList and java.lang.OutOfMemoryError - Stack Overflow
I am trying to make program that create an ArrayList of initial size of 1 and populate it with random numbers. Next, the ArrayList is cleared and the size of ArrayList is increased by 1 and again ... More on stackoverflow.com
🌐 stackoverflow.com
java - Behaviour of JVM during out of memory error? List s = new ArrayList<String>(); - Stack Overflow
The OutOfMemoryError probably occurs when the list(?) represented by s tries to allocate memory to store the string. If s is an ArrayList for instance, this operation can be quite expensive (since the ArrayList uses array doubling). More on stackoverflow.com
🌐 stackoverflow.com
java - Arraylist issue - Out of memory error - Stack Overflow
I am adding a parsed value to an ArrayList. I am getting a lot of parsed values in webservice. Because of this, I am getting an out of memory error. How do I avoid this? More on stackoverflow.com
🌐 stackoverflow.com
java - ArrayList Out of Memory Error - Stack Overflow
I am trying to Retrieve 100,000 records from an SQL database but I am having an Out of Memory Error when using ArrayList. How can I optimize my code to achieve this? How can I apply a flyweight d... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Stack Overflow
stackoverflow.com › questions › 49910835 › arraylist-java-lang-outofmemoryerror-java-heap-space › 49911217
ArrayList java.lang.OutOfMemoryError: Java heap space - Stack Overflow
April 19, 2018 - I also agree, so sort of "cached" list would seem like a better long term solution ... @MadProgrammer Even more confused now. This is not about performance. And only secondarily about the memory consumption per se. This is about the fact that in practice, you cannot have a Java Collection with more than 2^31 elements (and still expect it to work properly).
🌐
Stack Overflow
stackoverflow.com › questions › 42073539 › arraylist-out-of-memory-error
java - ArrayList Out of Memory Error - Stack Overflow
I am trying to Retrieve 100,000 records from an SQL database but I am having an Out of Memory Error when using ArrayList. How can I optimize my code to achieve this? How can I apply a flyweight design pattern to my code? Copyimport java.math.BigDecimal; import java.util.*; public class Foo { public List<Vo> Service(Vo vo) throws Exception { HashMap<Integer, Object> param = null; ArrayList<HashMap<String, Object>> getRows = null; HashMap<String, Object> row = null; Vo Vo = null; try { List<Vo> list = new ArrayList<Vo>(); if (Vo != null) { param = new HashMap(); if (Vo.getCode() != null) { param
🌐
Stack Overflow
stackoverflow.com › questions › 72026178 › arraylist-java-lang-outofmemoryerror-java-heap-space
collections - ArrayList - java.lang.OutOfMemoryError: Java heap space - Stack Overflow
@ДжейкМорган instead of reading all data [millions of records] at once, you form a batch of data [it's essentially grouping data in certain size for example 100] and write and repeat the same process until the whole data you need. How are you fetching data ? If you're using spring boot there is spring boot batch processing. Look around in documentation you'll find it. ... An ArrayList with a million objects consumes less than 6MB or maybe 12MB if you’re using flat 64 bit pointers.
Find elsewhere
🌐
Reddit
reddit.com › r/learnprogramming › [java] trouble adding an object to an arraylist
r/learnprogramming on Reddit: [Java] Trouble adding an object to an Arraylist
April 21, 2015 -

Hi, I'm doing some homework where I have to make a list of student objects and perform certain operations to them, and I need to have two classes, one using an Array and one using an ArrayList. My issue I'm having is I am inserting an object into the Arraylist at a specific index, but its throwing an error.

Here is my code:

public void insertStudent(String studentName, String newName, int q1, int q2, int q3, int q4, int q5) {
        Student newStudent = new Student(newName, q1, q2, q3, q4, q5); //Creates the new student using the given values
        for (int i = 0; i < myClass.size(); i++) //Goes through the list of students myClass
            if (myClass.get(i).name.equals(studentName)) //Checks if the student has the name requested to replace
            {
                myClass.add(i, newStudent);
            }

and this is the error I'm getting:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:3210)
	at java.util.Arrays.copyOf(Arrays.java:3181)
	at java.util.ArrayList.grow(ArrayList.java:261)
	at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
	at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
	at java.util.ArrayList.add(ArrayList.java:475)
	at TestStudent2.insertStudent(TestStudent2.java:42)
	at studentTester.main(studentTester.java:15)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

I'm honestly confused why I'm getting this, when I comment out

myClass.add(i, newStudent); 

I don't get the error, but it looks to me like it should work. Any help would be appreciated.

For what it's worth this is the code I used in the Array portion of the assignment, it works fine.

public void insertStudent(String studentName, String newName, int q1, int q2, int q3, int q4, int q5) {
        Student newStudent = new Student(newName, q1, q2, q3, q4, q5); //Creates the new student using the given values
        Student[] tempClass = new Student[myClass.length + 1];
        boolean t = false;
        for (int i = 0; i < myClass.length; i++)
            if (!myClass[i].name.equals(studentName) && !t)
                tempClass[i] = myClass[i];
            else if (myClass[i].name.equals(studentName)) {
                t = true;
                tempClass[i] = newStudent;
            } else if (t)
                tempClass[i] = myClass[i - 1];
        tempClass[tempClass.length - 1] = myClass[myClass.length - 1];
        myClass = tempClass;
    }

Also here are Pastebins for the entire project if you need some context.

Student.java

TestStudent.java (Using an Array)

TestStudent2.java (Using an ArrayList, the class with the issue)

studentTester.java (My tester class)

Top answer
1 of 2
3
You have an infinite loop occurring. When you see a name match, you insert a new student record into that index. This shifts the record you matched one to the right. When the ArrayList moves onto the next index, you see the previous record again and again insert, causing an infinite loop. Or to make it more clear, given a list: [Alice][Bob][John] and a new student Bob: [Alice][Bob][John] //Find a match [Alice][Bob][Bob][John] //Insert a new Bob into Index 1, prev Bob becomes Index 2 [Alice][Bob][Bob][John] //Finds a match with the shifted record [Alice][Bob][Bob][Bob][John] //Insert a new Bob into Index 2 Repeat until you run out of memory
2 of 2
2
public void insertStudent(String studentName, String newName, int q1, int q2, int q3, int q4, int q5) { Student newStudent = new Student(newName, q1, q2, q3, q4, q5); //Creates the new student using the given values for (int i = 0; i < myClass.size(); i++) //Goes through the list of students myClass if (myClass.get(i).name.equals(studentName)) //Checks if the student has the name requested to replace { myClass.add(i, newStudent); } Imagine that your "myClass" list contains students with the following names: Alice Bob Carol And you wanted to insert a student named "Bob". Here's what that code would do: i = 0 i is less than myClass.size() (3), let's execute the loop body The name of the student at index 0 does not equal "Bob"; do nothing. i= 1 i is less than myClass.size() (3), let's execute the loop body The name of the student at index 1 equals "Bob"; let's insert "Bob" at index 1. The list now looks like: Alice, Bob, Bob, Carol i = 2 i is less than myClass.size() (4), let's execute the loop body The name of the student at index 2 equals "Bob"; let's insert "Bob" at index 2. The list now looks like: Alice, Bob, Bob, Bob, Carol i = 3 i is less than myClass.size() (5), let's execute the loop body The name of the student at index 3 equals "Bob"; let's insert "Bob" at index 3. The list now looks like: Alice, Bob, Bob, Bob, Bob, Carol Repeat forever... Hopefully you can see where this is going. If it finds a student with the same name, it's going to keep looping forever, adding the new person object at each index. As the list gets bigger and bigger, it requires more and more memory; until you get an OutOfMemoryError. You probably want to add a break statement after calling myClass.add(i, newStudent), to exit out of the loop.
🌐
Last9
last9.io › blog › java-lang-outofmemoryerror
Java OutOfMemoryError: Causes, Fixes & Heap Space Tuning | Last9
February 19, 2026 - For example, LinkedList has different memory characteristics than ArrayList. // ArrayList stores everything in a contiguous array · // Good for random access, but expensive for frequent insertions ... For better observability in your Java applications, check out this guide on getting started with the OpenTelemetry Java SDK. Let’s look at some patterns that frequently cause these errors:
Top answer
1 of 3
3

Look at your loop:

while(j<campos.length){
    nombres_reuniones.add(campos[j]);
}

How do you anticipate that ever finishing? You don't modify j. Given that you don't make any change to j after declaring it and assigning it a value of 0 right at the start, it would be much clearer as:

for (int j = 0; j < campos.length; j++) {
    nombres_reuniones.add(campos[j]);
}

Or better:

for (String item : campos) {
    nombres_reuniones.add(item);
}

Or even simpler:

nombres_reunions.addAll(Arrays.asList(campos));

Additionally, your earlier code can be simpler. Look at this:

String aux2 = null;
aux2 = aux.replace("[", "");
aux2= aux2.replace("]", "");

Why bother assigning aux2 an initial value of null which you then immediately overwrite? Additionally, you can easily chain the method calls. It would be neater as:

String aux2 = aux.replace("[", "").replace("]", "");

And in fact, you can just chain the whole of the string manipulation together from start to finish:

String[] campos = jsonReuniones.getString("nombres")
                               .replace("[", "")
                               .replace("]", "")
                               .split(",");
nombres_reunions.addAll(Arrays.asList(campos));

(I'd stop there, rather than inlining even that expression...)

2 of 3
3

You're not advancing the loop:

while (j < campos.length) {
    nombres_reuniones.add(campos[j]);
    j++; // without this, you'll loop forever!
}

What's happening is that you're adding an infinite amount of "campos" to the ArrayList, exhausting all the memory available to your program in the process.

Remember: a loop's condition must be false at some point for the loop to end. If you forget to advance the loop (in this case, by incrementing the j variable) the condition will always be true and the loop will never exit, therefore creating an infinite loop.

🌐
Stack Overflow
stackoverflow.com › questions › 40640736 › adding-object-to-arraylist-gives-outofmemory-in-android
java - Adding object to arraylist gives outofmemory in android - Stack Overflow
public static ArrayList personData = new ArrayList(); On running the above code I get the OutOfMemory error in Android. ... 16 11:21:28.230 20236-20236/com.app.congress.congressapp E/AndroidRuntime: FATAL EXCEPTION: main Process: com.app.congress.congressapp, PID: 20236 java.lang.OutOfMemoryError: Failed to allocate a 69748 byte allocation with 54912 free bytes and 53KB until OOM at java.util.ArrayList.add(ArrayList.java:118) at com.app.congress.congressapp.ByState$GetAllStates.onPostExecute(ByState.java:112) at com.app.congress.congressapp.ByState$GetAllStates.onPostExecute(ByState.java:49) a
🌐
Stack Overflow
stackoverflow.com › questions › 57057913 › java-lang-outofmemoryerror-on-adding-element-in-arraylist
android - java.lang.OutOfMemoryError on adding element in arraylist - Stack Overflow
Reading file names from the device and add them into ArrayList for handling the same files name but add method of ArrayList throwing exception. CopyFatal Exception: java.lang.OutOfMemoryError: Failed to allocate a 55380616 byte allocation with 25165824 free bytes and 25MB until OOM, max allowed footprint 534834552, growth limit 536870912 at java.util.Arrays.copyOf + 3139(Arrays.java:3139) at java.util.Arrays.copyOf + 3109(Arrays.java:3109) at java.util.ArrayList.grow + 275(ArrayList.java:275) at java.util.ArrayList.ensureExplicitCapacity + 249(ArrayList.java:249) at java.util.ArrayList.ensureCapacityInternal + 241(ArrayList.java:241) at java.util.ArrayList.add + 467(ArrayList.java:467)
🌐
TutorialsPoint
tutorialspoint.com › out-of-memory-exception-in-java
Out of memory exception in Java:\\n
September 6, 2019 - There are 3 types of errors in OutOfMemoryError − · Java heap space. GC Overhead limit exceeded. Permgen space. Live Demo · public class SpaceErrorExample { public static void main(String args[]) throws Exception { Float[] array = new Float[10000 * 100000]; } } Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at sample.SpaceErrorExample.main(SpaceErrorExample.java:7) Live Demo · import java.util.ArrayList; import java.util.ListIterator; public class OutOfMemoryExample{ public static void main(String args[]) { //Instantiating an ArrayList object ArrayList<String> list
🌐
Stack Overflow
stackoverflow.com › questions › 42078002 › arraylist-add-causing-outofmemory-error
android - ArrayList.add() causing OutOfMemory error? - Stack Overflow
For the first time today, I've met an OutOfMemory Error. I'm trying to calculate moving averages out of some data into an ArrayList, and had a crash at the first .add() step. The method is shown be...