如何修复java中的内存泄漏

时间:2015-07-10 22:40:23

标签: java memory-leaks

我正在尝试编写一个从steam获取字符串化json对象的程序,并使用该对象来确定我是否可以在蒸汽市场上购买商品。

它有效,但我似乎得到了大量的内存泄漏,我不知道如何解决这个问题,因为我是一个初学程序员。这是代码:

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Scanner;


public class SteamMarketAlert {

    @SuppressWarnings("unused")
    private JAlertWindow alert;
    private URL jsonUrl;
    private float walletValue;
    private boolean itemBuyable;

    public SteamMarketAlert(URL itemUrl, float walletValue)
    {
        this.itemBuyable = false;
        this.jsonUrl = getJSONurl(itemUrl);
        this.walletValue = walletValue;
    }

    private URL getJSONurl(URL itemUrl)
    {
        String jsonString = itemUrl.toString();

        String firstPart = jsonString.substring(0, jsonString.indexOf("market/") + "market/".length());

        String appid = jsonString.split("/")[5];
        String marketHashName = jsonString.split("/")[6];

        String secondPart = "priceoverview/?currency=2&appid=" + appid + "&market_hash_name=" + marketHashName;

        try {
            return new URL(firstPart + secondPart);
        } catch (MalformedURLException e) {
            System.err.println("Failed to create json url");
            return null;
        }

    }

    public void checkMarket()
    {
        Thread thread = new Thread(){
            @Override
            public void run(){
                try {
                    while(!itemBuyable)
                    {
                        sleep(5000);                        
                        if(isBuyable(getPagehtml()))
                            itemBuyable = true;
                    }
                    alert = new JAlertWindow();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }   
        };

        thread.start();


    }

    private boolean isBuyable(String pagehtml)
    {
        int firstIndex = pagehtml.indexOf(";") +1;


        float marketValue = Float.parseFloat(pagehtml.substring(firstIndex, firstIndex + pagehtml.substring(firstIndex, pagehtml.length()).indexOf("\"")));

        return (marketValue <= walletValue)? true:false;
    }

    private String getPagehtml(){

        try(Scanner scanner = new Scanner(jsonUrl.openConnection().getInputStream())) {

            scanner.useDelimiter("\\Z");
            return scanner.next();
        } catch (IOException e) {               
            e.printStackTrace();
            return null;
        }

    }

    public static void main(String[] args)
    {
        try {
            float walletValue =  82.64f;
            URL itemUrl = new     URL("http://steamcommunity.com/market/listings/730/StatTrak%E2%84%A2%20P90%20%7C%20Asiimov%20%28Factory%20New%29");
            SteamMarketAlert sma = new SteamMarketAlert(itemUrl,walletValue);
            sma.checkMarket();


        } catch (MalformedURLException e) {

            e.printStackTrace();
        }

    }
}

我已将问题缩小到checkMarket()方法。但是,我似乎无法弄清楚发生了什么。你能指出我如何解决这个问题(并且可能指出我代码中的所有缺陷),注意JAlertWindow对象只显示一个带有“CAN BUY”的JFrame - 没什么特别的。

编辑:我更新了代码,因为发布和用户告诉我存在try-with-resource块。感谢所有帮助我理解java垃圾收集工作方式的人。 :!)

3 个答案:

答案 0 :(得分:1)

在获得OutOfMemoryException或者看到不断的垃圾回收之前,它可能不是Java中的内存泄漏。

在10分钟内使用18MB并不像是内存泄漏,这就是Java的工作原理。如果你真的想确定,你可以打开详细的GC并查看它收集的频率,但我认为你还没有真正的问题。

答案 1 :(得分:0)

您正在获取html页面,因此必须在每次获取时在内存中分配一些对象(String等)。稍后(一旦不再使用)这些对象将被删除并且内存被GC标记为空闲。

很抱歉有一个非常简单的解释。如果你想了解更多,只需阅读有关java GC,堆结构等的内容。

答案 2 :(得分:-4)

为什么不运行Java Profiler?我建议使用YourKit。我用它来查找服务器上存在任何内存泄漏的原因。它非常适合连接删除应用程序;你应该玩弄它。

这是一个关于如何查找内存泄漏的自己视频的链接; Link

如果您需要更多帮助,请快速阅读docs