我遇到了Java对象的奇怪行为。我有两个不同版本的ComponentPlane.class。差异由******
标记。
第一个工作版
package app.pathsom.som.output;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
import app.pathsom.som.map.Lattice;
import app.pathsom.som.map.Node;
public class ComponentPlane extends JPanel{
private Lattice lattice;
private int componentNumber;
private double minValue;
private double maxValue;
private double origMinValue;
private double origMaxValue;
public ComponentPlane(Lattice lattice, int componentNumber){
this.lattice = new Lattice();
this.componentNumber = componentNumber;
initLattice(lattice);
initComponentPlane();
}
private void initLattice(Lattice lattice){
this.lattice.setLatticeHeight(lattice.getLatticeHeight());
this.lattice.setLatticeWidth(lattice.getLatticeWidth());
this.lattice.setNumberOfNodeElements(lattice.getNumberOfNodeElements());
this.lattice.initializeValues();
this.lattice.setNodeHeight(lattice.getNodeHeight());
this.lattice.setNodeWidth(lattice.getNodeWidth());
this.lattice.setTotalNumberOfNodes(lattice.getTotalNumberOfNodes());
for(int i = 0; i < lattice.getTotalNumberOfNodes(); i++){
******this.lattice.getLatticeNode()[i] = new Node(lattice.getLatticeNode()[i]);******
}
}
}
第二个非工作版本的唯一区别是这个功能替换上面的功能
private void initLattice(Lattice lattice){
//same code here
for(int i = 0; i < lattice.getTotalNumberOfNodes(); i++){
******this.lattice.getLatticeNode()[i] = lattice.getLatticeNode()[i];******
}
}
我还尝试过做第三个非工作版本......
private void initLattice(Lattice lattice){
//same code here
******this.lattice.setLatticeNode(lattice.getLatticeNode());******
}
Node.class中的构造函数(在第一个WORKING版本中使用了WHICH就是这个......
public Node (Node node){
this.xPos = node.xPos;
this.yPos = node.yPos;
this.numOfElements = node.numOfElements;
this.cluster = -1;
this.nodeIndex = node.getNodeIndex();
for(int i = 0; i < this.numOfElements; i++){
this.addElement(node.getDoubleElementAt(i));
}
}
Lattice.class
public class Lattice {
private int latticeWidth;
private int latticeHeight;
private int numOfNodeElements;
private int nodeWidth;
private int nodeHeight;
private int totalNumOfNodes;
private Node[] latticeNodes;
private final int MAP_RADIUS = 225;
public Lattice(int latticeWidth, int latticeHeight, int numOfNodeElements){
this.latticeWidth = latticeWidth;
this.latticeHeight = latticeHeight;
this.numOfNodeElements = numOfNodeElements;
initializeLattice();
}
public Lattice(){
this(10, 10, 3);
}
public void initializeValues(){
totalNumOfNodes = this.latticeHeight * this.latticeWidth;
latticeNodes = new Node[totalNumOfNodes]; //specify the array of nodes
nodeWidth = (int) Math.floor(450/this.latticeWidth);
nodeHeight = (int) Math.floor(450/this.latticeHeight);
}
protected void initializeLattice(){
totalNumOfNodes = this.latticeHeight * this.latticeWidth;
latticeNodes = new Node[totalNumOfNodes];
nodeWidth = (int) Math.floor(450/this.latticeWidth);
nodeHeight = (int) Math.floor(450/this.latticeHeight);
//initialize colors
for(int i = 0; i <totalNumOfNodes; i++){
latticeNodes[i] = new Node(((i % this.latticeWidth) * nodeWidth) + nodeWidth / 2,
((i / this.latticeWidth) * nodeHeight ) + nodeHeight/2, numOfNodeElements, i);
latticeNodes[i].setNodeColor(new Color((int)(latticeNodes[i].getDoubleElementAt(0)
* 255), (int)(latticeNodes[i].getDoubleElementAt(1) * 255), (int) (latticeNodes[i].getDoubleElementAt(2) * 255)));
}
}
public int getLatticeHeight(){
return latticeHeight;
}
public void setLatticeHeight(int latticeHeight){
this.latticeHeight = latticeHeight;
}
public Node[] getLatticeNode(){
return latticeNodes;
}
public void setLatticeNode(Node[] latticeNodes){
this.latticeNodes = latticeNodes;
}
public int getLatticeWidth(){
return latticeWidth;
}
public void setLatticeWidth(int latticeWidth){
this.latticeWidth = latticeWidth;
}
public int getNodeHeight(){
return nodeHeight;
}
public int getNodeWidth(){
return nodeWidth;
}
public void setNodeHeight(int nodeHeight){
this.nodeHeight = nodeHeight;
}
public void setNodeWidth(int nodeWidth){
this.nodeWidth = nodeWidth;
}
public int getNumberOfNodeElements(){
return numOfNodeElements;
}
public void setNumberOfNodeElements(int numOfNodeElements){
this.numOfNodeElements = numOfNodeElements;
}
public int getTotalNumberOfNodes(){
return totalNumOfNodes;
}
public void setTotalNumberOfNodes(int totalNumberOfNodes){
this.totalNumOfNodes = totalNumberOfNodes;
}
}
某个Visualization.class启动所有这些操作并存储ComponentPlane数组。这是函数
public void initComponentPlanes(){
componentPlanes = new ComponentPlane[somtrainer.getLattice().getNumberOfNodeElements()];
int size = somtrainer.getLattice().getNumberOfNodeElements();
for(int i = 0; i < size; i++){
System.out.println(i + ": " + inputData.getVariableLabels()[i] + " size : " + size);
componentPlanes[i] = new ComponentPlane(somtrainer.getLattice(), i);
componentPlanes[i].setBounds((240 - 225)/2, (280-240)/2, 225, 240);
componentPlanes[i].setOrigMaxMin(maxMin[i][0], maxMin[i][1]);
}
}
我的问题是
第一个工作正常。它为每个组件编号创建HEATMAPS或COMPONENTPLANES(意味着它们彼此不同)但我不能将它用作引用(&#34; this.addElement ....&#的******的行) Node.class构造函数中的34;)给出了OUTOFMEMORY错误,所以只要我有许多COMPONENTPLANES,它就会LAGS和FREEZES。 (我实际上在做一个COMPONENTPlane对象的ARRAY)所以我决定尝试第二个和第三个选项。我已经增加了我的堆大小所以这是不可能的
如果我使用第二个和第三个,我最终没有LAGS,即使有大量的ComponentPlanes(可能因为创建新的Node对象或idk而占用的内存较少)但这些会产生错误的热图。所有的热图都是一样的。事实是,所有的热图都像是ComponentPlanes数组的最后一个元素(例如,如果我有十个ComponentPlane对象,所有的热图看起来都像第十个组件对象)
所有的热图都是这样的 - 与数组中的最后一张热图相同:
有没有办法让第二个和第三个工作?
答案 0 :(得分:0)
显而易见的区别在于,在第一个中您创建了新节点,而在其他节点中,您重新使用旧节点。这条线
this.lattice.getLatticeNode()[i] = lattice.getLatticeNode()[i];
将一个对象设置为另一个。如果稍后lattice.getLatticeNode()[i]
的属性发生更改,则也会影响this.lattice.getLatticeNode()[i]
。这可能导致难以发现的错误。相反,行
this.lattice.getLatticeNode()[i] = new Node(lattice.getLatticeNode()[i]);
正在创建一个与旧对象不同的新对象。但是,当然,这意味着您正在使用更多内存,因为现在您有两个对象而不是一个。
您可以采取一些措施来减少使用的内存量。 private final int MAP_RADIUS = 225;
可以设为静态,因此不会为每个节点创建常量的新副本。