3

私が作ったプロジェクトでは、メモリリークが発生しました。一部を修正するためにすべての関数を書き直しましたが、まだ1つ残っていました。

プログラムには、新しいパネルを挿入するたびに大きくなるパネルのオブジェクト配列があります。400パネルに達すると、最も古いパネルを削除してメモリを解放します。

私が理解していないのは次のとおりです。

tempPanels = new Panel[panels.Length];
Array.Copy(panels, 1, tempPanels, 0, panels.Length - 1);//delete the oldest history log (the first of the array)
panels = null; //empty object array
panels = new Panel[tempPanels.Length + 1]; //set new length
tempPanels.CopyTo(panels, 0);//restore panels

上記のコードを使用すると、メモリ使用量が増え続けます...パネルをnullに設定する前に、最初にパネルを破棄する必要がある理由を誰かに説明してもらえますか?

tempPanels = new Panel[panels.Length];
Array.Copy(panels, 1, tempPanels, 0, panels.Length - 1);//delete the oldest history log (the first of the array)
panels[0].Dispose();
panels = null; //empty object array
panels = new Panel[tempPanels.Length + 1]; //set new length
tempPanels.CopyTo(panels, 0);//restore panels

前もって感謝します!

編集@スティーブB:
プログラムは新しいpanel currentPanel;
パネルを作成します:新しいパネルがあるとき、私はcurrentPanelを宣言します:currentPanel = new Panel();
その後、私はこの関数を呼び出します:setCurrentPanelConfiguration:

public void setCurrentPanel()
{
  currentPanel.Name = "panel" + panels.Length;
  currentPanel.Size = new System.Drawing.Size(485, 75);
  currentPanel.BackColor = Color.Transparent;
}

スクロールのバグを修正するために、currentPanelを配置するPanelHistoryPanelを使用します。

HistoryPanel.Controls.Add(currentPanel);

次に、ユーザー名、現在の時刻、アバターのすべてのコントロールを追加します。

パネルを保存するには、上記のようにスペースを作成した後、それを配列パネルに追加します。
panels[panels.Length-1] = currentPanel;

履歴に最新のものが表示されるため、配列を使用します。これを行うには、すべてのパネルを80ピクセル下にシフトする必要があります。

4

2 に答える 2

11

何かを設定nullすると、それは破棄されないため、逆参照されるだけです。ガベージコレクターは、null参照をチェックするために割り当てを監視していません。必要な場合(他のすべてが等しい場合)、または明示的に指示された場合に実行します。

つまり、nullメモリ管理は別のものだからです。

于 2013-01-08T09:02:29.130 に答える
3

Grant Thomasが言ったことに加えて、List<Panel>管理がはるかに簡単なを使用してみませんか?

コードは次のようになります(としてpanels宣言されていると仮定しますList<Panel>):

Panel p = panels[0];
panels.RemoveAt(0);  // This removes the first element

p.Dispose(); // This disposes of the element

コードを保持したい場合は、次のように読み替えてください。

tempPanels = new Panel[panels.Length];
Array.Copy(panels, 1, tempPanels, 0, panels.Length - 1);//delete the oldest history log (the first of the array)

// Dispose of every element in the array
for (int i = 0; i < panels.Length; i++)
    panels[i].Dispose();

// The following line is unneccessary, as the variable is re-assigned anyway
// panels = null; //empty object array

panels = new Panel[tempPanels.Length + 1]; //set new length
tempPanels.CopyTo(panels, 0);//restore panels
于 2013-01-08T09:07:12.747 に答える