Dear Forum,
I have some trouble with the CreMe virtual machine (NSICom) so I will just give it a try to post here. As NSICom support just does not answer my questions anymore (seems that I am already on there ignore list), I hope one of you can give me a hint on what's going wrong here.
The actual problem is a leaking of memory. After ages of reviewing my own code I figured out, that this is not my fault. Since it has something to do with threads, I wrote a simple test class:
import java.awt.BorderLayout;
import java.awt.*;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.swing.*;
import javax.swing.*;
public class MemoryTest extends JFrame implements Runnable, ActionListener
{
private final static short MODE_SSL = 1;
private static final String AC_RUN_GC = "RUN_GC", AC_END = "END", AC_EXIT = "EXIT", AC_MEM_INFO = "MEM_INFO",
AC_OBJECT_MAP = "OBJECT_MAP";
private final short m_sMode;
private int m_iCycles;
private final Runnable runnable;
private final Thread m_thCollector;
private final LinkedList m_llThreads;
private static URL testUrl;
private JTextArea m_taLog;
public MemoryTest(final short p_sMode, final int p_iCycles, final String p_strTestUrl)
throws MalformedURLException
{
super("CreMe Memory tester");
m_sMode = p_sMode;
m_iCycles = p_iCycles;
runnable = new Runnable()
{
public void run()
{
for (int i = 0; i < 100; i++)
{
Math.random();
try
{
Thread.sleep(20);
}
catch (InterruptedException e)
{}
}
}
};
m_thCollector = new Thread()
{
public void run()
{
//... collect fiished threads
}
};
m_llThreads = new LinkedList();
testUrl = new URL(p_strTestUrl);
initComponents();
}
public void run()
{
log("Starting test (MODE " + (m_sMode == MODE_SSL ? "SSL" : "THREAD") + " | CYCLES: " + m_iCycles + "...");
long lLoopCount = 0;
while (m_iCycles != 0)
{
switch (m_sMode)
{
case MODE_SSL:
runSSLTest();
break;
default:
runThreadTest();
break;
}
if (lLoopCount++ % 1000 == 0)
{
actionPerformed(new ActionEvent(this, 0, AC_MEM_INFO));
actionPerformed(new ActionEvent(this, 0, AC_OBJECT_MAP));
}
synchronized (this)
{
if (m_iCycles > 0)
{
m_iCycles--;
}
}
}
log("Test finished!");
}
private void runThreadTest()
{
while (m_llThreads.size() > 100)
{
sleep(100);
}
Thread t = new Thread(runnable);
t.start();
log("Started thread: " + t.getName());
synchronized (m_llThreads)
{
m_llThreads.add(t);
}
if (!m_thCollector.isAlive())
{
m_thCollector.start();
}
sleep((int) (Math.random() * 100));
}
private void runSSLTest()
{
try
{
testUrl.openConnection();
}
catch (IOException e)
{
log("runSSLTest: " + e.getMessage());
e.printStackTrace();
}
}
private void initComponents()
{
// ... create ui
}
private final static SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy_HHmmss: ");
private void log(String p_strMsg)
{
// ... log to screen and file
}
private void sleep(final int p_iMillis)
{
try
{
Thread.sleep(p_iMillis);
}
catch (InterruptedException e)
{}
}
public void actionPerformed(final ActionEvent e)
{
if (e.getActionCommand().equals(AC_END))
{
synchronized (this)
{
m_iCycles = 0;
}
log("Test canceled by user.");
}
else if (e.getActionCommand().equals(AC_MEM_INFO) || e.getActionCommand().equals(AC_RUN_GC))
{
if (e.getActionCommand().equals(AC_RUN_GC))
{
System.gc();
}
log("Free...: " + (Runtime.getRuntime().freeMemory() / 1024) + " kb\n");
log("Total...: " + (Runtime.getRuntime().totalMemory() / 1024) + " kb\n");
}
else if (e.getActionCommand().equals(AC_EXIT))
{
log("Exiting application...");
dispose();
System.exit(0);
}
else if (e.getActionCommand().equals(AC_EXIT))
{
log("Printing object map of all objects...");
creme.ObjectMap.printAll();
log("...done");
}
}
public static void main(final String[] args)
{
if (args.length != 3)
{
System.out.println("Parameter help: MODE(1=SSL,0=THREAD) CYCLES(-1=forever) URL(testURL for SSL test)");
return;
}
try
{
new Thread(new MemoryTest(Short.parseShort(args[0]), Integer.parseInt(args[1]), args[2])).start();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
I ran it from the command line like that and monitored the system's memory with the Windows CE performance monitor tool:
creme.exe -wd /Temp MemoryTester 0 -1 https://my.ssl.url/path/file.jsp
After about an hour it came to this: [monitor results|http://i625.photobucket.com/albums/tt340/swebble/crememem.png]
As you can see, the memory load of the system steadily increases. The heap memory of the application remains more or less on the same level of only a few kb. Can someone commit this problem or even figure out what's wrong?
When I use the SSL test mode which actually just opens ssl connections, the behavior is the same. I guess that the ssl implementation makes much use of threads internally.
Best regards and thanks in advance,
Sebastian