C#에서 cgi를 실험하고 있습니다. 크기를 조절할 수있는 사각형 안에 정사각형 (화살표가있는)을 움직일 수있는 앱을 만들었습니다. 크기를 조정하기 위해 하나 이상의 직사각형을 페인팅합니다. 충돌 클래스를 사용하여 가장자리를지나 이동을 제한합니다.너무 많은 메모리를 사용하는 C# 콘솔 CGI 그래픽
모든 것이 잘된 것처럼 보이지만 메모리 사용에 대해서는 우려합니다. 크기를 늘리면 메모리 소비가 증가하고 GC가 시작됩니다.
누군가이 누출을 찾도록 도와 줄 수 있습니까? 나는 그 사용량을 급증시키는 잘못된 것을하고 있습니까? 버퍼를 잘못 사용합니까?
EDIT :: 실제로,이 코드 줄이 메모리 사용을 유발하는 원인을 발견했습니다. 이 코드 블록을 주석 처리 한 후, 내 프로그램은 2GB 대신 16MB 만 사용했습니다.
if (player.rectHeight >= tempWidth)
{
Program.bufferedGraphics = context.Allocate(Program.graphics,
new Rectangle(0, 0, Convert.ToInt32(player.rectWidth) + 100,
Convert.ToInt32(player.rectHeight) + 100));
}
감사합니다.
코드
class Program
{
static Graphics graphics;
static BufferedGraphics bufferedGraphics;
static Player player;
static Collision collision;
static Utility utility;
static SByte value = 0;
static float tempWidth = 500;
static void Main()
{
Program.player = new Player();
Program.utility = new Utility();
Program.collision = new Collision();
Console.CursorVisible = false;
Process process = Process.GetCurrentProcess();
Program.graphics = Graphics.FromHdc(GetDC(process.MainWindowHandle));
BufferedGraphicsContext context = BufferedGraphicsManager.Current;
context.MaximumBuffer = new Size(Console.WindowWidth, Console.WindowHeight);
Program.bufferedGraphics = context.Allocate(Program.graphics, new Rectangle(0, 0, Convert.ToInt32(player.rectWidth),
Convert.ToInt32(player.rectHeight)));
while (true)
{
collision.worldEdges = new Collision.WorldEdges()
{
rightBorder = Convert.ToInt32(player.rectWidth),
leftBorder = 0,
topBorder = 0,
bottomBorder = Convert.ToInt32(player.rectHeight),
};
if (player.rectHeight >= tempWidth)
{
Program.bufferedGraphics = context.Allocate(Program.graphics, new Rectangle(0, 0, Convert.ToInt32(player.rectWidth) + 100,
Convert.ToInt32(player.rectHeight) + 100));
}
//Debug.Print(Convert.ToString(player.rectHeight));
// Debug.Print(Convert.ToString(player.x));
//Debug.Print(Convert.ToString(player.x- collision.worldEdges.rightBorder));
if (player.y > collision.worldEdges.bottomBorder-19.7f) // if on the edge, clamp its movement
{
player.y = collision.worldEdges.bottomBorder-19.8f;
}
if (player.x > collision.worldEdges.rightBorder - 19.7)
{
player.x = collision.worldEdges.rightBorder - 19.8f;
}
else
{
Program.player.DoMove();
}
Program.player.ResizeScreen(out value); //check whether resize the rectangle
if (value ==1) //g decrease size
{
bufferedGraphics.Graphics.FillRectangle(Brushes.Black, 0, 0,
Convert.ToInt32(player.rectWidth), Convert.ToInt32(player.rectHeight));
player.rectHeight -= 0.08f;
player.rectWidth -= 0.08f;
tempWidth = player.rectWidth;
}
if (value == -1) //h increase size
{
bufferedGraphics.Graphics.FillRectangle(Brushes.Black, 0, 0,
Convert.ToInt32(player.rectWidth), Convert.ToInt32(player.rectHeight));
player.rectHeight += 0.08f;
player.rectWidth += 0.08f;
//Program.bufferedGraphics = context.Allocate(Program.graphics, new Rectangle(0, 0, 320,200));
bufferedGraphics.Graphics.FillRectangle(Brushes.Green, 0, 0, Convert.ToInt32(player.rectWidth),
Convert.ToInt32(player.rectHeight));
tempWidth = player.rectWidth;
}
else
{
bufferedGraphics.Graphics.FillRectangle(Brushes.Green, 0, 0, Convert.ToInt32(player.rectWidth),
Convert.ToInt32(player.rectHeight));
}
Program.player.DrawPlayer(Program.bufferedGraphics.Graphics, Brushes.Blue); //draw player controlled cube
Program.bufferedGraphics.Render(Program.graphics); //finally render on screen
}
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetDC(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern short GetKeyState(int nVirtKey);
}
class Player //detect input and set player size and it's movement
{
const int LEFT = 0x25;
const int UP = 0x26;
const int RIGHT = 0x27;
const int DOWN = 0x28;
const int G = 0x47;
public float rectWidth = 200, rectHeight = 200;
public float x;
public float y;
public Player()
{
this.x = 0;
this.y = 0;
}
public void DoMove()
{
if ((GetKeyState(LEFT) | 0x8000) > 0 && this.x < rectWidth-10)
{
this.x += 0.1f;
}
if ((GetKeyState(RIGHT) | 0x8000) > 0 && this.x > 0)
{
this.x -= 0.1f;
}
if ((GetKeyState(UP) | 0x8000) > 0)
{
this.y += 0.1f;
}
if ((GetKeyState(DOWN) | 0x8000) > 0 && this.y > 0)
{
this.y -= 0.1f;
}
}
public void DrawPlayer(Graphics g, Brush color)
{
g.FillRectangle(color, this.x , this.y , 20, 20);
}
public void ResizeScreen(out SByte value)
{
if ((GetKeyState(G) | 0x8000) < 0)
{
value = 1;
}
else if ((GetKeyState(0x48) | 0x8000) < 0)
{
value = -1;
}
else
{
value = 0;
}
}
[DllImport("user32.dll")]
static extern short GetKeyState(int nVirtKey);
}
class Collision //used for colliding with other objects and world boundaries
{
public struct WorldEdges
{
public int leftBorder;
public int rightBorder;
public int topBorder;
public int bottomBorder;
}
public WorldEdges worldEdges;
}
답변 해 주셔서 감사합니다. 확실히 코드를 업데이트 할 것입니다. –
나는 그 누출의 원인을 강조하기 위해 나의 질문을 편집했다. –