【发布时间】:2015-09-29 19:54:01
【问题描述】:
我目前正在尝试编写一个程序,从 Steam 获取字符串化的 json 对象,并使用该对象来确定我是否可以在 Steam 市场上购买商品。
它有效,但是我似乎遇到了大量的内存泄漏,我不知道如何解决这个问题,因为我是一个初学者程序员。代码如下:
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 垃圾收集工作原理的人。 :)!
【问题讨论】:
-
一方面,不需要在线程中的
while循环之外声明html。实际上,您根本不需要StringBuilder,只需从getPagehtml返回scanner.next()的值。并不是说这会对内存泄漏产生太大影响,只是有点笨拙。 -
请描述“内存泄漏”的确切含义以及如何证明它的存在。
-
好吧,当我将它导出到 .jar 文件并启动 jar 时,它在任务管理器中运行时,内存值会随着时间的推移而上升,所以从大约 12,000 K 开始,然后在大约 10 分钟内达到大约 30,000 K ......并且继续上升:P。这就是我所说的内存泄漏。
-
@AndyTurner 如果我在扫描仪仍处于打开状态时返回值,我该如何关闭扫描仪?我的意思是“返回scanner.next():”肯定会在不关闭扫描仪的情况下让我脱离getPagehtml()方法吗?我的印象是我必须关闭扫描仪。
-
如果您没有收到
OutOfMemoryException,您没有问题。
标签: java memory-leaks