Java 应用程序正在消耗越来越多的内存,有时高达 2GB,
Java Application is consuming more and more Memory, which sometimes is up to 2GB,
我有一个 JavaFX 应用程序,它包含一个用于数据处理并在用户界面中显示结果的后台线程。
我创建了以下数据处理代码:
public static void runningThread(){
long startTime = java.lang.System.nanoTime();
WSN wsn = new WSN(100, 100, 30, 60, 200);
wsn.initializeNodePosition();
wsn.alphaNodesDead = wsn.nodeNumber/2;
BaseStation BS = new BaseStation(); //the BS is created
BS.x = 125;
BS.y = 50;
BS.maxRadius = 65;
BS.energyModel = new NOEnergyModel();
wsn.BS = BS;
BS.wsn = wsn;
Thread queryThread = new Thread() {
public void run() {
System.out.println("Start");
for(int m=0; m<1000; m++){
System.out.println(m);
wsn.protocol = new HEED(wsn);
wsn.generateHomogeneousWSN(HEEDNODE.class, new MITModel(), new SimpleAggregation());
wsn.protocol.setRadiusAndNeighbors();
boolean running = true;
while(running){
wsn.roundPerformed++;
wsn.protocol.election_cluster_formation(); //cluster formation
wsn.defineStandardCHRouting(); //defines the routing at CH level
wsn.protocol.runRound();
System.out.println(wsn.roundPerformed);
if(wsn.deadNodeList.size() >= wsn.alphaNodesDead){
long stopTime = java.lang.System.nanoTime();
System.out.println("end: " + (stopTime-startTime) / 1000000000.0);
running = false;
}
}
}
}
};
queryThread.start();
}
问题是在我 运行 应用程序并单击 "Start" 按钮以 运行 "runningThread()" 功能后,内存消耗和 CPU 是越来越高,当达到2GB以上内存和CPU的90%时,"for(int m=0; m<1000; m++)"循环变得很慢。我在每个循环开始之前清除所有对象。
一旦任何对象失去对它的所有引用,JVM 是否会自动回收内存以供重用?
JVM 垃圾收集何时开始'undefined'。
我认为你的主要问题是你的内部 while 循环不停地不断测试 - 尝试在 while 循环中添加 Thread.sleep(100)。
内存泄漏可能出现在您代码中的任何位置。使用 VisualVM 探查器或 IDE 中的内置探查器来找到它。
JVM 会为未使用的对象回收内存,但直到 GC 进程 运行s 才会这样做。我猜测 runRound
在内部分配了很多对象。 GC 很可能在循环的下一次迭代时没有 运行,因此分配新内存,然后一次又一次,等等
最终它会达到 JVM 的上限(-Xmx
参数),然后 GC 将开始更积极地释放未使用的对象,但你实际上没有很多控制它何时发生。
使用 VisualVM 等工具将帮助您确定问题所在。它会告诉你分配的字节数和实际使用的字节数之间的区别。您还可以查看 GC 进程何时发生。 JDK.
中包含 VisualVM
另一种选择是 runRound
正在分配它保持某种全局引用的对象。同样,仔细使用 VisualVM 应该可以让您识别这一点。
您描述的症状强烈暗示存在内存泄漏:
- 内存利用率不断提高
- 应用程序变得越来越慢,因为 GC 花费的时间越来越长,而且 运行s 越来越频繁。
- 最终,您得到
OutOfMemoryError
并且应用程序崩溃。
内存泄漏通常发生在应用程序创建越来越多的对象时,这些对象由于仍然可访问而无法被垃圾回收。
一般的解决办法是找到内存泄漏的原因(通常是一个错误)并修复它。有很多工具可以在 Java 程序中查找内存泄漏,Whosebugs 上也有关于如何做到这一点的信息。关于如何做。
- 强制 GC 运行 无济于事。 GC 已经 运行ning ...并且无法回收对象,因为它们仍然可以访问。
- 增加堆大小可能也无济于事。它只是将不可避免的减速推迟到应用程序 运行.
的后期
Does JVM will reclaims memory automatically for reuse once any of the object lose all the reference to it ?
是的。
而且您不需要强制 GC 运行。
对象未被回收这一事实意味着它们仍然可以访问。换句话说,您应该确保对象变得不可访问的代码不起作用。
我有一个 JavaFX 应用程序,它包含一个用于数据处理并在用户界面中显示结果的后台线程。 我创建了以下数据处理代码:
public static void runningThread(){
long startTime = java.lang.System.nanoTime();
WSN wsn = new WSN(100, 100, 30, 60, 200);
wsn.initializeNodePosition();
wsn.alphaNodesDead = wsn.nodeNumber/2;
BaseStation BS = new BaseStation(); //the BS is created
BS.x = 125;
BS.y = 50;
BS.maxRadius = 65;
BS.energyModel = new NOEnergyModel();
wsn.BS = BS;
BS.wsn = wsn;
Thread queryThread = new Thread() {
public void run() {
System.out.println("Start");
for(int m=0; m<1000; m++){
System.out.println(m);
wsn.protocol = new HEED(wsn);
wsn.generateHomogeneousWSN(HEEDNODE.class, new MITModel(), new SimpleAggregation());
wsn.protocol.setRadiusAndNeighbors();
boolean running = true;
while(running){
wsn.roundPerformed++;
wsn.protocol.election_cluster_formation(); //cluster formation
wsn.defineStandardCHRouting(); //defines the routing at CH level
wsn.protocol.runRound();
System.out.println(wsn.roundPerformed);
if(wsn.deadNodeList.size() >= wsn.alphaNodesDead){
long stopTime = java.lang.System.nanoTime();
System.out.println("end: " + (stopTime-startTime) / 1000000000.0);
running = false;
}
}
}
}
};
queryThread.start();
}
问题是在我 运行 应用程序并单击 "Start" 按钮以 运行 "runningThread()" 功能后,内存消耗和 CPU 是越来越高,当达到2GB以上内存和CPU的90%时,"for(int m=0; m<1000; m++)"循环变得很慢。我在每个循环开始之前清除所有对象。 一旦任何对象失去对它的所有引用,JVM 是否会自动回收内存以供重用?
JVM 垃圾收集何时开始'undefined'。
我认为你的主要问题是你的内部 while 循环不停地不断测试 - 尝试在 while 循环中添加 Thread.sleep(100)。
内存泄漏可能出现在您代码中的任何位置。使用 VisualVM 探查器或 IDE 中的内置探查器来找到它。
JVM 会为未使用的对象回收内存,但直到 GC 进程 运行s 才会这样做。我猜测 runRound
在内部分配了很多对象。 GC 很可能在循环的下一次迭代时没有 运行,因此分配新内存,然后一次又一次,等等
最终它会达到 JVM 的上限(-Xmx
参数),然后 GC 将开始更积极地释放未使用的对象,但你实际上没有很多控制它何时发生。
使用 VisualVM 等工具将帮助您确定问题所在。它会告诉你分配的字节数和实际使用的字节数之间的区别。您还可以查看 GC 进程何时发生。 JDK.
中包含 VisualVM另一种选择是 runRound
正在分配它保持某种全局引用的对象。同样,仔细使用 VisualVM 应该可以让您识别这一点。
您描述的症状强烈暗示存在内存泄漏:
- 内存利用率不断提高
- 应用程序变得越来越慢,因为 GC 花费的时间越来越长,而且 运行s 越来越频繁。
- 最终,您得到
OutOfMemoryError
并且应用程序崩溃。
内存泄漏通常发生在应用程序创建越来越多的对象时,这些对象由于仍然可访问而无法被垃圾回收。
一般的解决办法是找到内存泄漏的原因(通常是一个错误)并修复它。有很多工具可以在 Java 程序中查找内存泄漏,Whosebugs 上也有关于如何做到这一点的信息。关于如何做。
- 强制 GC 运行 无济于事。 GC 已经 运行ning ...并且无法回收对象,因为它们仍然可以访问。
- 增加堆大小可能也无济于事。它只是将不可避免的减速推迟到应用程序 运行. 的后期
Does JVM will reclaims memory automatically for reuse once any of the object lose all the reference to it ?
是的。
而且您不需要强制 GC 运行。
对象未被回收这一事实意味着它们仍然可以访问。换句话说,您应该确保对象变得不可访问的代码不起作用。