内存泄露,造成原因有new完以后不释放,代码放在循环中 ,new 大对象,内存很快耗光,举个例子,干净的纸上用铅笔乱画东西,整个纸面画完以后,就没地方画了,要想再画的话,得用橡皮擦了。借别人的东西,老是不归还,再借用的话,就不借给了。房间里堆满了东西,再往进放的话,就放不进去了。等等,生活中好多这样的例子。看一下下面代码
using (MemoryStream ms = new MemoryStream())
{
try
{
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
}
catch
{
return false;
}
var runner = session.GetRunner();
var tensor = CreateTensorFromImage(ms.GetBuffer());
runner.AddInput(graph["input"][0], tensor).Fetch(graph["output"][0]);
var output = runner.Run();
var result = output[0];
var rshape = result.Shape;
if (result.NumDims != 2 || rshape[0] != 1)
{
var shape = "";
foreach (var d in rshape)
{
// shape += $"{d} ";
}
shape = shape.Trim();
Environment.Exit(1);
return false;
}
bool jagged = true;
var bestIdx = 0;
float best = 0;
if (jagged)
{
var probabilities = ((float[][])result.GetValue(jagged: true))[0];
for (int i = 0; i < probabilities.Length; i++)
{
if (probabilities[i] > best)
{
bestIdx = i;
best = probabilities[i];
}
}
}
else
{
var val = (float[,])result.GetValue(jagged: false);
for (int i = 0; i < val.GetLength(1); i++)
{
if (val[0, i] > best)
{
bestIdx = i;
best = val[0, i];
}
}
}
this.Invoke(new Action(() =>
{
//nizh modify
string tmpStr = labels[bestIdx];
if (tmpStr.IndexOf("sandship") != -1)
{
label1.Text = "XXXX_" + tmpStr;
}
else { label1.Text = tmpStr; }
label1.Refresh();
}
)
);
if (tensor != null)
{
tensor.Dispose();
tensor = null;
}
if (result != null)
{
result.Dispose();
result = null;
}
if (ms != null)
{
ms.Close();
ms.Dispose();
}
if (bmp != null)
{
bmp.Dispose();
//bmp = null;
}
}
GC.Collect();
GC.SuppressFinalize(this);
查看带有Dispose()的代码行,起初是没有这些的,一起动程序,4个g内存很快就没了。
GC.Collect();垃圾回收
var tensor = TFTensor.CreateString(contents);
TFGraph graph;
TFOutput input, output;
// Construct a graph to normalize the image
ConstructGraphToNormalizeImage(out graph, out input, out output);
// Execute that graph to normalize this one image
using (var session = new TFSession(graph))
{
var normalized = session.Run(
inputs: new[] { input },
inputValues: new[] { tensor },
outputs: new[] { output });
if (session!=null)
{
session.Dispose();
}
if (tensor!=null)
{
tensor.Dispose();
}
if (graph!=null)
{
graph.Dispose();
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
return normalized[0];
}
查看Dispose代码行,销毁就不泄露了。不销毁就泄露。
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
有必要时用上边3行代码回收内存。
const int W = 224;
const int H = 224;
const float Mean = 117;
const float Scale = 1;
graph = new TFGraph();
input = graph.Placeholder(TFDataType.String);
output = graph.Div(
x: graph.Sub(
x: graph.ResizeBilinear(
images: graph.ExpandDims(
input: graph.Cast(
graph.DecodeJpeg(contents: input, channels: 3), DstT: TFDataType.Float),
dim: graph.Const(0, "make_batch")),
size: graph.Const(new int[] { W, H }, "size")),
y: graph.Const(Mean, "mean")),
y: graph.Const(Scale, "scale"));
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();