Monday, October 29, 2018

[Java] Testing Heap Memory

I tried to test heap code provided by stackify.com. I used Java VisualVM to monitor heap memory and Swing application from Oracle site to make it easier to execute the test. 
The visualVM can be found in the Java installation folder/bin directory. Double-click visualvm.exe file to run the application.


This is the class that I created with code lifted from stackify.com and Oracle site.



import java.util.ArrayList;
import java.util.Random;

public class MemoryTester extends javax.swing.JFrame {


private static final long serialVersionUID = 1L;
private static Random random = new Random();
private static final ArrayList<Double> list = new ArrayList<Double>(100000000);

public MemoryTester(){

init();
}

private void init(){
setTitle("Memory Tester");
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

javax.swing.JButton    memLeakButton = new javax.swing.JButton();
javax.swing.JButton    noMemLeakButton = new javax.swing.JButton();
javax.swing.JLabel   memLeakLabel = new javax.swing.JLabel();
javax.swing.JLabel    noMemLeakLabel = new javax.swing.JLabel();
 
    memLeakLabel.setText("Memory Leak");
    noMemLeakLabel.setText("NO Memory Leak");
    memLeakButton.setText("Test");
    noMemLeakButton.setText("Test");
    
    memLeakButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                System.out.println("Memory leak...");
                try {
testLeak();
} catch (InterruptedException e) {
e.printStackTrace();
}
            }
        });
    
    
    noMemLeakButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                System.out.println("NO Memory leak...");
                addElementsToTheList();
                System.gc();
                Thread.sleep(10000);
            }
        });
        
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(memLeakButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(memLeakLabel))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(noMemLeakButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(noMemLeakLabel)))
                .addContainerGap(27, Short.MAX_VALUE))
        );

        layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {noMemLeakButton, memLeakButton});

        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(memLeakButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(memLeakLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(noMemLeakButton)
                    .addComponent(noMemLeakLabel))
                .addContainerGap(21, Short.MAX_VALUE))
        );
        pack();
}



private void testLeak() throws InterruptedException{
for (int i = 0; i < 100000000; i++) {
        list.add(random.nextDouble());
    }
    
    System.gc();
    Thread.sleep(10000); // to allow GC do its j
}


private void addElementsToTheList(){
    ArrayList<Double> list = new ArrayList<Double>(100000000);
    Random randomx = new Random();
    for (int i = 0; i < 100000000; i++) {
        list.add(randomx.nextDouble());
    }
}

/**

 * @param args
 */
public static void main(String[] args) {
 java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new MemoryTester().setVisible(true);
            }
        });

}


}




Running the code will open this Swing application.




Running 'memory leak' code will display this heap graph, there is no drop in heap memory.






Running 'no memory leak' code will display the graph below. Notice the drop in heap memory which means object was garbage collected.





No comments:

Post a Comment