如何减少2D类Minecraft项目中的新对象创建数量?
兄弟,看了你的代码片段,我发现你每次调用move方法都要新建一个GridPane,这可不太妙——频繁创建新对象会让Java的垃圾回收器忙个不停,游戏帧率很容易掉下来。给你几个实用的优化思路,都是咱做类似项目踩过坑总结出来的:
复用GridPane,别每次都新建
把GridPane作为Generation类的成员变量,初始化的时候创建一次就行,不用在move方法里每次都new GridPane()。之后调用move时,只需要清空现有子元素,再重新添加新的块。这样就避免了频繁创建新的GridPane对象,减少了不必要的内存分配。
比如在类里加个成员变量:private GridPane gridPane = new GridPane();然后
move方法里直接用这个gridPane,调用gridPane.getChildren().clear()清空后再添加新元素就行。缓存图片资源,避免重复加载
你现在每次使用草方块、圆石的图片时,是不是都要重新加载Image对象?这既浪费IO资源,又会重复创建对象。可以把这些Image对象作为类的成员变量,在构造方法里提前加载好,之后用的时候直接复用。
示例代码:private Image grassImage; private Image cobblestoneImage; public Generation() throws URISyntaxException { grassImage = new Image(getClass().getResource(grass_path).toURI().toString()); cobblestoneImage = new Image(getClass().getResource(cobblestone_path).toURI().toString()); }之后创建
ImageView时直接用这些缓存好的Image就行,不用每次都重新加载。用对象池复用UI元素
不要每次循环都新建ImageView或者Rectangle,可以维护一个“闲置对象池”。比如准备两个列表,分别存闲置的草方块ImageView和圆石ImageView。当需要显示某个块时,先从池子里拿闲置的元素;如果池子空了再新建;当块移出视野时,把对应的元素放回池子,而不是直接丢弃。这样能大幅减少新对象的创建,相机频繁移动时效果特别明显。
简单的实现示例:private List<ImageView> unusedGrassViews = new ArrayList<>(); private List<ImageView> unusedCobblestoneViews = new ArrayList<>(); // 获取草方块ImageView的方法 private ImageView getGrassView() { if (!unusedGrassViews.isEmpty()) { return unusedGrassViews.remove(0); } ImageView view = new ImageView(grassImage); view.setFitWidth(BLOCK_SIZE); view.setFitHeight(BLOCK_SIZE); return view; } // 回收草方块ImageView的方法 private void recycleGrassView(ImageView view) { gridPane.getChildren().remove(view); unusedGrassViews.add(view); }减少循环内的临时变量
看你代码里的循环逻辑,尽量把能复用的变量提到循环外面。比如一些不需要每次循环都重新初始化的变量,提前定义好,减少每次循环的临时对象分配,积少成多也能减轻GC的压力。
备注:内容来源于stack exchange,提问作者Lamowy

