Java堆空间::内存不足错误

时间:2015-01-21 06:09:58

标签: java mysql

我试图在MySql dB中添加50000个数据,其中只包含2列(id,description)。但是我能够添加到30000数据但是当它试图添加更多数据时它会给我以下错误

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Unknown Source)
    at java.util.Arrays.copyOf(Unknown Source)
    at java.util.ArrayList.grow(Unknown Source)
    at java.util.ArrayList.ensureExplicitCapacity(Unknown Source)
    at java.util.ArrayList.ensureCapacityInternal(Unknown Source)

我还尝试在Run Configuration下的VM参数中添加参数。还尝试更改weblogic> bin中的setDomainEnv.cmd .Below是代码。任何可以帮助我的人::

public class SequenceGenerator {
    private static final String CHAR_LIST = 
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
    private static final int RANDOM_STRING_LENGTH = 5;

    private static final String jsonFilePath ="D:/Assignments/Sequence/file.json";
    static HashMap hm =  new HashMap();
    static Set mapSet = null;
    int count=1;
    /**
     * This method generates random string 
     * and stores the values in a hashmap
     */
    public void generateRandomString(){


        while(count<=50000){/*Change 10000 to 30000*/
            StringBuffer randStr = new StringBuffer();
            for(int i=0; i<RANDOM_STRING_LENGTH; i++){
                int number = getRandomNumber();
                char ch = CHAR_LIST.charAt(number);
                randStr.append(ch);
            }
            hm.put(count, randStr);
            mapSet = hm.entrySet();
            //System.out.println(randStr.toString());
            count++;
        }

    }

    /**
     * This method generates random numbers
     * @return int
     */
    private int getRandomNumber() {
        int randomInt = 0;
        Random randomGenerator = new Random();
        randomInt = randomGenerator.nextInt(CHAR_LIST.length());
        if (randomInt - 1 == -1) {
            return randomInt;
        } else {
            return randomInt - 1;
        }
    }

    public static DataSource getMySQLDataSource() throws Exception {
        Properties props = new Properties();
        FileInputStream fis = null;
        MysqlDataSource mysqlDS = null;

        try {
            fis = new FileInputStream("D:/Assignments/Sequence/db.properties");
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        props.load(fis);
        mysqlDS = new MysqlDataSource();
        mysqlDS.setURL(props.getProperty("MYSQL_DB_URL"));
        mysqlDS.setUser(props.getProperty("MYSQL_DB_USERNAME"));
        mysqlDS.setPassword(props.getProperty("MYSQL_DB_PASSWORD"));
        return mysqlDS;
    }

    public static void main(String[] args) throws Exception 
    {
        SequenceGenerator sg = new SequenceGenerator();
        sg.generateRandomString();
        System.out.println("Current size of Heap::"+Runtime.getRuntime().totalMemory());
        System.out.println("Max size of Heap::"+Runtime.getRuntime().maxMemory());
        Connection con = null;
        Statement stmt = null;
        ResultSet rs = null;
        PreparedStatement pst = null;
        FileWriter fw = new FileWriter(jsonFilePath);
        try {
            con = getMySQLDataSource().getConnection();
            stmt = con.createStatement();
            System.out.println("Displaying key and value pair of HashMap..");
            Iterator mapIterator = mapSet.iterator();
            while(mapIterator.hasNext())
            {
                Map.Entry mapEntry = (Map.Entry)mapIterator.next();
                //int key = Integer.parseInt(mapEntry.getKey().toString());
                //String value = mapEntry.getValue().toString();
                pst = con.prepareStatement("insert into nodes_test values (?,?)");
                pst.setInt(1, Integer.parseInt(mapEntry.getKey().toString()));
                pst.setString(2, mapEntry.getValue().toString());
                pst.executeUpdate();
                System.out.println(Integer.parseInt(mapEntry.getKey().toString()));
            }
            fw.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                if(rs != null) rs.close();
                if(stmt != null) stmt.close();
                if(pst != null) pst.close();
                if(con != null) con.close();
                System.out.println("Free Memory::"+Runtime.getRuntime().freeMemory());
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

}

3 个答案:

答案 0 :(得分:1)

我建议在生成String后立即存储它,而不是存储在HashMap中。如果您在保存后未在应用中使用数据,则应避免使用内存。

您可以在generateRandomString()方法中引入Connection参数,并从main()方法传递它。创建随机字符串后,立即根据连接调用store。我也会尝试重复使用预备语句。

答案 1 :(得分:0)

首先使用以下代码找出您的堆内存

public static void main(String[]args){

    long totalHeapSize = Runtime.getRuntime().totalMemory();

    //Total heap size
    System.out.println("Total Heap Size is: " + totalHeapSize);
}

如果使用以下环境变量

,现在更改堆大小
SET _JAVA_OPTIONS = -Xms512m -Xmx1024m


使用以下命令

java -Xms512m -Xmx1024m TestData.java

答案 2 :(得分:0)

不要浪费记忆力。只需将生成的值直接写入数据库即可。

这是您的代码,没有不必要的内存使用。我没有做任何其他尝试来优化代码。

public class SequenceGenerator
{
    private static final String CHAR_LIST =
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
    private static final int RANDOM_STRING_LENGTH = 5;
    private static final Random RANDOM = new Random();

    /**
     * Generates and returns a random string
     */
    public String generateRandomString() {
        char[] chars = new char[RANDOM_STRING_LENGTH];
        for (int i = 0; i < RANDOM_STRING_LENGTH; i++) {
            int number = RANDOM.nextInt(CHAR_LIST.length());
            chars[i] = CHAR_LIST.charAt(number);
        }
        return new String(chars);
    }

    public static DataSource getMySQLDataSource() throws Exception {
        Properties props = new Properties();
        MysqlDataSource mysqlDS = null;

        FileInputStream fis = new FileInputStream(
                "D:/Assignments/Sequence/db.properties");
        try {
            props.load(fis);
        } finally {
            fis.close();
        }
        mysqlDS = new MysqlDataSource();
        mysqlDS.setURL(props.getProperty("MYSQL_DB_URL"));
        mysqlDS.setUser(props.getProperty("MYSQL_DB_USERNAME"));
        mysqlDS.setPassword(props.getProperty("MYSQL_DB_PASSWORD"));
        return mysqlDS;
    }

    public static void main(String[] args) throws Exception {
        SequenceGenerator sg = new SequenceGenerator();
        Connection con = getMySQLDataSource().getConnection();
        try {
            PreparedStatement pst = con.prepareStatement("insert into nodes_test values (?,?)");
            for (int i = 0; i < 50000; i++) {
                pst.setInt(1, i);
                pst.setString(2, sg.generateRandomString());
                pst.executeUpdate();
                System.out.println(i);
            }
            pst.close();
        } finally {
            con.close();
        }
    }
}