我有一个300k +元素的树形图,我需要循环。我期待它需要一段时间,但它已经到了它看起来像悬挂的地步。我插入了一个println语句来跟踪我在其中的位置,实际上当它达到某些点时它暂停了一两秒,然后继续。最终(大约140k),它完全停止,然后最终自我终止该程序。
我正在尝试为我的项目制作树图创建者和查看器。它是一棵n树,但并非所有分支都有n个孩子。然而,为了使它符合我的需要,我需要制作一个包含所有可能子项的完整树,直到达到指定的大小,然后迭代它以检查大小,更改大小,位置和存在。
//ArrayList<Button[]> buttons is passed in
double width = 0;
double height = 0;
Group g = new Group();
Scene s = new Scene(g);
Button[] array = buttons.get(buttons.size() - 1);
int temp = 1;
for(int i = 0; i < array.length; ++i) {
Button b = array[i];
g.getChildren().add(b);
g.applyCss();
g.layout();
width = width > b.getWidth() ? width : b.getWidth();
height = height > b.getHeight() ? height : b.getHeight();
g.getChildren().remove(b);
System.out.println(temp++);
}
编辑(因为我忘了说这个):我首先尝试了for-each循环,但它有相同的问题,交换到这个以查看它是否更好并收到相同的结果
编辑:滞后的主要来源是来自applyCSS()或layout(),但我仍然怀疑,因为它暂停在看似随机的低至16k并且偶尔会在其余部分暂停,直到它在170k到300k之间死亡
编辑:我已经通过忽略占位符按钮来制定我自己的解决方案,因此忽略了树中的几乎所有内容,但我保持开放,希望有人知道实际的解决方案并发布,以便其他人也可以受益。目前的问题是弄清楚如何应用CSS并布置数十万个节点以确定它们的大小
不要考虑每个循环与正常循环,数组列表和类似的微优化,这可能会给你一个毫秒最多。迭代一百万个元素是非常便宜的,重要的是你用它们做什么。
它看起来像一个内存泄漏,你的内存消耗似乎增加,然后GC启动导致一个微小的暂停,但它无法回收足够的内存,所以它被调用的频率越来越高,最后该过程死亡,因为它是徒劳的。
也许添加然后删除按钮会保留一些额外的信息,可能是场景或组。
尝试java -verbose:gc ...
或在外部观看记忆。在调试器中,检查组件以找出g.getChildren().remove(b)
之后的更改和停留。
考虑重新创建组件,可能每1000 Scene
s使用一个新的Group
/ Button
或完全放下按钮。请注意,视觉元素中不应存在任何长期因素,因此在需要时从数据中重新创建按钮应该是微不足道的(不可见的Button
是一种廉价的数据结构(并且创建速度非常快),而屏幕上的按钮可以容纳更多资源)。
您是否尝试过使用增强型for循环?这是一个例子
for (int YourNumberHere : YourArrayHEre)
{
Button b = array[i];
g.getChildren().add(b);
g.applyCss();
g.layout();
width = width > b.getWidth() ? width : b.getWidth();
height = height > b.getHeight() ? height : b.getHeight();
g.getChildren().remove(b);
System.out.println(temp++);
}