【问题标题】:java.lang.OutOfMemoryError: Java heap space error in my codejava.lang.OutOfMemoryError:我的代码中出现 Java 堆空间错误
【发布时间】:2014-02-04 04:40:13
【问题描述】:

我正在尝试读取 JSON 文件并执行一些操作。此 JSON 文件位于 Amazon S3 中,大小为 500MB。未来的文件将以 TeraBytes 为单位。下面是我的代码。

public void createHash() throws IOException
    {
        System.out.println("Hash Creation Started");

        strBuffer = new StringBuffer("");


        try
        {
            //List all the Buckets
            List<Bucket>buckets = s3.listBuckets();

            for(int i=0;i<buckets.size();i++)
            {
                System.out.println("- "+(buckets.get(i)).getName());
            }


            //Downloading the Object
            System.out.println("Downloading Object");
            S3Object s3Object = s3.getObject(new GetObjectRequest(inputBucket, inputFile));
            System.out.println("Content-Type: "  + s3Object.getObjectMetadata().getContentType());


            //Read the JSON File
            /*BufferedReader reader = new BufferedReader(new InputStreamReader(s3Object.getObjectContent()));
            while (true) {
                String line = reader.readLine();
                if (line == null) break;

               // System.out.println("    " + line);
                strBuffer.append(line);

            }*/

            JSONTokener jTokener = new JSONTokener(new BufferedReader(new InputStreamReader(s3Object.getObjectContent())));
            jsonArray = new JSONArray(jTokener);

            System.out.println("Json array length: "+jsonArray.length());


            for(int i=0;i<jsonArray.length();i++)
            {
                JSONObject jsonObject1 = jsonArray.getJSONObject(i);
                StringBuffer hashIndex = new StringBuffer("");

                //Add Title and Body Together to the list
                String titleAndBodyContainer = jsonObject1.getString("title")+" "+jsonObject1.getString("body");


                //Remove full stops and commas
                titleAndBodyContainer = titleAndBodyContainer.replaceAll("\\.(?=\\s|$)", " ");
                titleAndBodyContainer = titleAndBodyContainer.replaceAll(",", " ");
                titleAndBodyContainer = titleAndBodyContainer.toLowerCase();


                //Create a word list without duplicated words
                StringBuilder result = new StringBuilder();

                HashSet<String> set = new HashSet<String>();
                for(String s : titleAndBodyContainer.split(" ")) {
                    if (!set.contains(s)) {
                        result.append(s);
                        result.append(" ");
                        set.add(s);
                    }
                }
                //System.out.println(result.toString());


                //Re-Arranging everything into Alphabetic Order
                String testString = "acarpous barnyard gleet diabolize acarus creosol eaten gleet absorbance";
                //String testHash = "057        1$k     983    5*1      058     52j    6!v   983     03z";

                String[]finalWordHolder = (result.toString()).split(" ");
                Arrays.sort(finalWordHolder);


                //Navigate through text and create the Hash
                for(int arrayCount=0;arrayCount<finalWordHolder.length;arrayCount++)
                {


                    if(wordMap.containsKey(finalWordHolder[arrayCount]))
                    {
                        hashIndex.append((String)wordMap.get(finalWordHolder[arrayCount]));
                    }

                }

                //System.out.println(hashIndex.toString().trim());

                jsonObject1.put("hash_index", hashIndex.toString().trim()); //Add the Hash to the JSON Object
                jsonObject1.put("primary_key", i); //Create the primary key
                jsonObjectHolder.add(jsonObject1); //Add the JSON Object to the JSON collection

                jsonHashHolder.add(hashIndex.toString().trim());

                System.out.println("JSON Number: "+i);

                //System.out.println(Arrays.toString(finalWordHolder));
                //System.out.println("- "+hashIndex.toString());

                //break;

            }

            System.out.println("Hash Creation Completed");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

但是,执行代码时出现以下错误。

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:2894)
        at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:117)
        at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:589)
        at java.lang.StringBuffer.append(StringBuffer.java:337)
        at com.amazonaws.util.json.JSONTokener.nextString(JSONTokener.java:284)
        at com.amazonaws.util.json.JSONTokener.nextValue(JSONTokener.java:348)
        at com.amazonaws.util.json.JSONObject.<init>(JSONObject.java:222)
        at com.amazonaws.util.json.JSONTokener.nextValue(JSONTokener.java:351)
        at com.amazonaws.util.json.JSONArray.<init>(JSONArray.java:125)
        at HashCreator.createHash(HashCreator.java:215)
        at HashCreator.<init>(HashCreator.java:61)
        at Main.main(Main.java:9)
[root@ip-172-31-45-123 JarFiles]#

它谈到第 215 行,就是这个代码 - jsonArray = new JSONArray(jTokener);

这里发生了什么,我该如何解决?

编辑

这是我的 JSON 代码:

[
    {
        "hash_index": "00102x05h06l0aj0dw",
        "body": "Who's signing up for Obamacare?",
        "_type": "ArticleItem",
        "title": "Who's signing up for Obamacare? - Jan. 13, 2014",
        "source": "money.cnn.com",
        "primary_key": 0,
        "last_crawl_date": "2014-01-14",
        "url": "http://money.cnn.com/2014/01/13/news/economy/obamacare-enrollment/index.html"
    },
    {
        "hash_index": "00102x05h06l0aj0dw0iz0kn0l@0t#0",
        "body": "Who's signing up for Obamacare?",
        "_type": "ArticleItem",
        "title": "Who's signing up for Obamacare? - Jan. 13, 2014",
        "source": "money.cnn.com",
        "primary_key": 1,
        "last_crawl_date": "2014-01-14",
        "url": "http://money.cnn.com/2014/01/13/news/economy/obamacare-enrollment/index.html"
    }
]

无论如何,请不要向我提供“增加堆大小”的解决方案。这不是解决方案,而是“膏药”。

【问题讨论】:

  • 文件只是一个大的 JSON 对象?
  • @SotiriosDelimanolis:您好,这是一个大的 JSON 文件。它是一个 JSON 数组。
  • @SotiriosDelimanolis:请看一下编辑。你可以理解:)
  • 是否可以在不耗尽内存的情况下逐行读取?我可能会这样做,并使用不同的 JSON 解析器(一个不会读取内存中所有内容的解析器)。
  • @ThomasMueller:我不知道。也许GSON?反正我从来没有用过这些。

标签: java json eclipse io amazon-s3


【解决方案1】:

只是增加你的堆大小:

java -Xmx2g myprogram

【讨论】:

  • OP要注意2g是内存的大小,根据你想做的改变。
【解决方案2】:

堆是存储对象实例的地方。考虑您的程序范围,尝试查看您是否正在创建在范围内保留的实例。这适用于调用您的 createHash() 的方法,它可能会在其范围内保留它自己的对象。

如果堆用完了,这可能表明在某个地方正在创建大量对象,并且可能存储在列表或其他数据结构中,这些对象正在保留它们并阻止垃圾收集器清理车间。

增加堆大小会有所帮助,但可能只会延迟问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-21
    • 2013-04-17
    • 1970-01-01
    • 2021-09-09
    • 2011-10-24
    • 1970-01-01
    • 2017-05-13
    • 1970-01-01
    相关资源
    最近更新 更多