OutOfMemoryException Kelas
Definisi
Penting
Beberapa informasi terkait produk prarilis yang dapat diubah secara signifikan sebelum dirilis. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Pengecualian yang dilemparkan ketika tidak ada cukup memori untuk melanjutkan eksekusi program.
public ref class OutOfMemoryException : Exception
public ref class OutOfMemoryException : SystemException
public class OutOfMemoryException : Exception
public class OutOfMemoryException : SystemException
[System.Serializable]
public class OutOfMemoryException : SystemException
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class OutOfMemoryException : SystemException
type OutOfMemoryException = class
inherit Exception
type OutOfMemoryException = class
inherit SystemException
[<System.Serializable>]
type OutOfMemoryException = class
inherit SystemException
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type OutOfMemoryException = class
inherit SystemException
Public Class OutOfMemoryException
Inherits Exception
Public Class OutOfMemoryException
Inherits SystemException
- Warisan
- Warisan
- Turunan
- Atribut
Keterangan
OutOfMemoryException menggunakan HRESULT COR_E_OUTOFMEMORY
, yang memiliki nilai 0x8007000E.
Untuk daftar nilai properti awal untuk instans OutOfMemoryException, lihat OutOfMemoryException konstruktor.
Catatan
Nilai properti yang diwariskan Data selalu null
.
Pengecualian OutOfMemoryException memiliki dua penyebab utama:
Anda mencoba memperluas StringBuilder objek di luar panjang yang ditentukan oleh propertinya StringBuilder.MaxCapacity .
Runtime bahasa umum tidak dapat mengalokasikan memori yang cukup berdampingan untuk berhasil melakukan operasi. Pengecualian ini dapat dilemparkan oleh penetapan properti atau panggilan metode apa pun yang memerlukan alokasi memori. Untuk informasi selengkapnya tentang penyebab OutOfMemoryException pengecualian, lihat posting blog "Kehabisan Memori" Tidak Merujuk ke Memori Fisik.
Jenis OutOfMemoryException pengecualian ini mewakili kegagalan besar. Jika Anda memilih untuk menangani pengecualian, Anda harus menyertakan
catch
blok yang memanggil Environment.FailFast metode untuk mengakhiri aplikasi Anda dan menambahkan entri ke log peristiwa sistem, seperti yang dilakukan contoh berikut.using System; public class Example { public static void Main() { try { // Outer block to handle any unexpected exceptions. try { string s = "This"; s = s.Insert(2, "is "); // Throw an OutOfMemoryException exception. throw new OutOfMemoryException(); } catch (ArgumentException) { Console.WriteLine("ArgumentException in String.Insert"); } // Execute program logic. } catch (OutOfMemoryException e) { Console.WriteLine("Terminating application unexpectedly..."); Environment.FailFast(String.Format("Out of Memory: {0}", e.Message)); } } } // The example displays the following output: // Terminating application unexpectedly...
open System try // Outer block to handle any unexpected exceptions. try let s = "This" let s = s.Insert(2, "is ") // Throw an OutOfMemoryException exception. raise (OutOfMemoryException()) with | :? ArgumentException -> printfn "ArgumentException in String.Insert" // Execute program logic. with :? OutOfMemoryException as e -> printfn "Terminating application unexpectedly..." Environment.FailFast $"Out of Memory: {e.Message}" // The example displays the following output: // Terminating application unexpectedly...
Module Example Public Sub Main() Try ' Outer block to handle any unexpected exceptions. Try Dim s As String = "This" s = s.Insert(2, "is ") ' Throw an OutOfMemoryException exception. Throw New OutOfMemoryException() Catch e As ArgumentException Console.WriteLine("ArgumentException in String.Insert") End Try ' Execute program logic. Catch e As OutOfMemoryException Console.WriteLine("Terminating application unexpectedly...") Environment.FailFast(String.Format("Out of Memory: {0}", e.Message)) End Try End Sub End Module ' The example displays the following output: ' Terminating application unexpectedly...
Beberapa kondisi di mana pengecualian dilemparkan dan tindakan yang dapat Anda ambil untuk menghilangkannya termasuk yang berikut ini:
Anda memanggil StringBuilder.Insert metode .
Anda mencoba meningkatkan panjang StringBuilder objek di luar ukuran yang ditentukan oleh propertinya StringBuilder.MaxCapacity . Contoh berikut mengilustrasikan OutOfMemoryException pengecualian yang dilemparkan oleh panggilan ke StringBuilder.Insert(Int32, String, Int32) metode ketika contoh mencoba menyisipkan string yang akan menyebabkan properti objek Length melebihi kapasitas maksimumnya.
using System;
using System.Text;
public class Example
{
public static void Main()
{
StringBuilder sb = new StringBuilder(15, 15);
sb.Append("Substring #1 ");
try {
sb.Insert(0, "Substring #2 ", 1);
}
catch (OutOfMemoryException e) {
Console.WriteLine("Out of Memory: {0}", e.Message);
}
}
}
// The example displays the following output:
// Out of Memory: Insufficient memory to continue the execution of the program.
open System
open System.Text
let sb = StringBuilder(15, 15)
sb.Append "Substring #1 "
|> ignore
try
sb.Insert(0, "Substring #2 ", 1)
|> ignore
with :? OutOfMemoryException as e ->
printfn $"Out of Memory: {e.Message}"
// The example displays the following output:
// Out of Memory: Insufficient memory to continue the execution of the program.
Imports System.Text
Module Example
Public Sub Main()
Dim sb As New StringBuilder(15, 15)
sb.Append("Substring #1 ")
Try
sb.Insert(0, "Substring #2 ", 1)
Catch e As OutOfMemoryException
Console.WriteLine("Out of Memory: {0}", e.Message)
End Try
End Sub
End Module
' The example displays the following output:
' Out of Memory: Insufficient memory to continue the execution of the program.
Anda dapat melakukan salah satu hal berikut ini untuk mengatasi kesalahan:
Ganti panggilan ke StringBuilder.StringBuilder(Int32, Int32) konstruktor dengan panggilan overload konstruktor lainnya StringBuilder . Kapasitas maksimum objek Anda StringBuilder akan diatur ke nilai defaultnya, yaitu Int32.MaxValue.
StringBuilder.StringBuilder(Int32, Int32) Panggil konstruktor dengan
maxCapacity
nilai yang cukup besar untuk mengakomodasi ekspansi apa pun ke StringBuilder objek.
Aplikasi Anda berjalan sebagai proses 32-bit.
Proses 32-bit dapat mengalokasikan maksimum 2GB memori mode pengguna virtual pada sistem 32-bit, dan memori mode pengguna virtual 4GB pada sistem 64-bit. Ini dapat membuatnya lebih sulit bagi runtime bahasa umum untuk mengalokasikan memori yang cukup berdada ketika alokasi besar diperlukan. Sebaliknya, proses 64-bit dapat mengalokasikan memori virtual hingga 8 TB. Untuk mengatasi pengecualian ini, kompilasi ulang aplikasi Anda untuk menargetkan platform 64-bit. Untuk informasi tentang menargetkan platform tertentu di Visual Studio, lihat Cara: Mengonfigurasi Proyek ke Platform Target.
Aplikasi Anda membocorkan sumber daya yang tidak dikelola
Meskipun pengumpul sampah dapat membebaskan memori yang dialokasikan untuk jenis terkelola, ia tidak mengelola memori yang dialokasikan untuk sumber daya yang tidak dikelola seperti handel sistem operasi (termasuk handel ke file, file yang dipetakan memori, pipa, kunci registri, dan handel tunggu) dan blok memori yang dialokasikan langsung oleh panggilan Windows API atau oleh panggilan ke fungsi alokasi memori seperti malloc
. Jenis yang menggunakan sumber daya yang tidak dikelola mengimplementasikan IDisposable antarmuka.
Jika Anda menggunakan jenis yang menggunakan sumber daya yang tidak dikelola, Anda harus yakin untuk memanggil metodenya IDisposable.Dispose ketika Anda telah selesai menggunakannya. (Beberapa jenis juga mengimplementasikan Close
metode yang identik dalam fungsi dengan Dispose
metode.) Untuk informasi selengkapnya, lihat topik Menggunakan Objek yang Mengimplementasikan IDisposable .
Jika Anda telah membuat jenis yang menggunakan sumber daya yang tidak dikelola, pastikan Anda telah menerapkan pola Buang dan, jika perlu, menyediakan finalizer. Untuk informasi selengkapnya, lihat Menerapkan metode Buang dan Object.Finalize.
Anda mencoba membuat array besar dalam proses 64-bit
Secara default, runtime bahasa umum dalam .NET Framework tidak mengizinkan objek tunggal yang ukurannya melebihi 2GB. Untuk mengambil alih default ini, Anda dapat menggunakan <pengaturan file konfigurasi gcAllowVeryLargeObjects> untuk mengaktifkan array yang ukuran totalnya melebihi 2 GB. Pada .NET Core, dukungan untuk array yang lebih besar dari 2 GB diaktifkan secara default.
Anda bekerja dengan kumpulan data yang sangat besar (seperti array, koleksi, atau himpunan data database) dalam memori.
Ketika struktur data atau himpunan data yang berada dalam memori menjadi sangat besar sehingga runtime bahasa umum tidak dapat mengalokasikan memori yang cukup berdampingan untuknya, hasil OutOfMemoryException pengecualian.
Untuk mencegah OutOfMemoryException pengecualian, Anda harus memodifikasi aplikasi Anda sehingga lebih sedikit data yang disimpan dalam memori, atau data dibagi menjadi segmen yang memerlukan alokasi memori yang lebih kecil. Contohnya:
Jika Anda mengambil semua data dari database lalu memfilternya di aplikasi untuk meminimalkan perjalanan ke server, Anda harus memodifikasi kueri untuk mengembalikan hanya subset data yang dibutuhkan aplikasi Anda. Saat bekerja dengan tabel besar, beberapa kueri hampir selalu lebih efisien daripada mengambil semua data dalam satu tabel lalu memanipulasinya.
Jika Anda menjalankan kueri yang dibuat pengguna secara dinamis, Anda harus memastikan bahwa jumlah rekaman yang dikembalikan oleh kueri dibatasi.
Jika Anda menggunakan array besar atau objek koleksi lain yang ukurannya menghasilkan OutOfMemoryException pengecualian, Anda harus memodifikasi aplikasi Anda untuk mengerjakan data dalam subset daripada bekerja dengan semuanya sekaligus.
Contoh berikut mendapatkan array yang terdiri dari 200 juta nilai floating-point lalu menghitung nilai rata-ratanya. Output dari contoh menunjukkan bahwa, karena contoh menyimpan seluruh array dalam memori sebelum menghitung rata-rata, dilemparkan OutOfMemoryException .
using System;
using System.Collections.Generic;
public class Example
{
public static void Main()
{
Double[] values = GetData();
// Compute mean.
Console.WriteLine("Sample mean: {0}, N = {1}",
GetMean(values), values.Length);
}
private static Double[] GetData()
{
Random rnd = new Random();
List<Double> values = new List<Double>();
for (int ctr = 1; ctr <= 200000000; ctr++) {
values.Add(rnd.NextDouble());
if (ctr % 10000000 == 0)
Console.WriteLine("Retrieved {0:N0} items of data.",
ctr);
}
return values.ToArray();
}
private static Double GetMean(Double[] values)
{
Double sum = 0;
foreach (var value in values)
sum += value;
return sum / values.Length;
}
}
// The example displays output like the following:
// Retrieved 10,000,000 items of data.
// Retrieved 20,000,000 items of data.
// Retrieved 30,000,000 items of data.
// Retrieved 40,000,000 items of data.
// Retrieved 50,000,000 items of data.
// Retrieved 60,000,000 items of data.
// Retrieved 70,000,000 items of data.
// Retrieved 80,000,000 items of data.
// Retrieved 90,000,000 items of data.
// Retrieved 100,000,000 items of data.
// Retrieved 110,000,000 items of data.
// Retrieved 120,000,000 items of data.
// Retrieved 130,000,000 items of data.
//
// Unhandled Exception: OutOfMemoryException.
open System
let getData () =
let rnd = Random()
[| for i = 1 to 200000000 do
rnd.NextDouble()
if i % 10000000 = 0 then
printfn $"Retrieved {i:N0} items of data." |]
let getMean values =
let sum = Array.sum values
sum / float values.Length
let values = getData ()
// Compute mean.
printfn $"Sample mean: {getMean values}, N = {values.Length}"
// The example displays output like the following:
// Retrieved 10,000,000 items of data.
// Retrieved 20,000,000 items of data.
// Retrieved 30,000,000 items of data.
// Retrieved 40,000,000 items of data.
// Retrieved 50,000,000 items of data.
// Retrieved 60,000,000 items of data.
// Retrieved 70,000,000 items of data.
// Retrieved 80,000,000 items of data.
// Retrieved 90,000,000 items of data.
// Retrieved 100,000,000 items of data.
// Retrieved 110,000,000 items of data.
// Retrieved 120,000,000 items of data.
// Retrieved 130,000,000 items of data.
//
// Unhandled Exception: OutOfMemoryException.
Imports System.Collections.Generic
Module Example
Public Sub Main()
Dim values() As Double = GetData()
' Compute mean.
Console.WriteLine("Sample mean: {0}, N = {1}",
GetMean(values), values.Length)
End Sub
Private Function GetData() As Double()
Dim rnd As New Random()
Dim values As New List(Of Double)()
For ctr As Integer = 1 To 200000000
values.Add(rnd.NextDouble)
If ctr Mod 10000000 = 0 Then
Console.WriteLine("Retrieved {0:N0} items of data.",
ctr)
End If
Next
Return values.ToArray()
End Function
Private Function GetMean(values() As Double) As Double
Dim sum As Double = 0
For Each value In values
sum += value
Next
Return sum / values.Length
End Function
End Module
' The example displays output like the following:
' Retrieved 10,000,000 items of data.
' Retrieved 20,000,000 items of data.
' Retrieved 30,000,000 items of data.
' Retrieved 40,000,000 items of data.
' Retrieved 50,000,000 items of data.
' Retrieved 60,000,000 items of data.
' Retrieved 70,000,000 items of data.
' Retrieved 80,000,000 items of data.
' Retrieved 90,000,000 items of data.
' Retrieved 100,000,000 items of data.
' Retrieved 110,000,000 items of data.
' Retrieved 120,000,000 items of data.
' Retrieved 130,000,000 items of data.
'
' Unhandled Exception: OutOfMemoryException.
Contoh berikut menghilangkan OutOfMemoryException pengecualian dengan memproses data masuk tanpa menyimpan seluruh himpunan data dalam memori, menserialisasikan data ke file jika perlu untuk mengizinkan pemrosesan lebih lanjut (baris ini dikomentari dalam contoh, karena dalam hal ini mereka menghasilkan file yang ukurannya lebih besar dari 1GB), dan mengembalikan rata-rata terhitung dan jumlah kasus ke rutinitas panggilan.
using System;
using System.IO;
public class Example
{
public static void Main()
{
Tuple<Double, long> result = GetResult();
Console.WriteLine("Sample mean: {0}, N = {1:N0}",
result.Item1, result.Item2);
}
private static Tuple<Double, long> GetResult()
{
int chunkSize = 50000000;
int nToGet = 200000000;
Random rnd = new Random();
// FileStream fs = new FileStream(@".\data.bin", FileMode.Create);
// BinaryWriter bin = new BinaryWriter(fs);
// bin.Write((int)0);
int n = 0;
Double sum = 0;
for (int outer = 0;
outer <= ((int) Math.Ceiling(nToGet * 1.0 / chunkSize) - 1);
outer++) {
for (int inner = 0;
inner <= Math.Min(nToGet - n - 1, chunkSize - 1);
inner++) {
Double value = rnd.NextDouble();
sum += value;
n++;
// bin.Write(value);
}
}
// bin.Seek(0, SeekOrigin.Begin);
// bin.Write(n);
// bin.Close();
return new Tuple<Double, long>(sum/n, n);
}
}
// The example displays output like the following:
// Sample mean: 0.500022771458399, N = 200,000,000
open System
// open System.IO
let getResult () =
let chunkSize = 50000000
let nToGet = 200000000
let rnd = Random()
// use fs = new FileStream(@".\data.bin", FileMode.Create)
// use bin = new BinaryWriter(fs)
// bin.Write 0
let mutable n = 0
let mutable sum = 0.
for _ = 0 to int (ceil (nToGet / chunkSize |> float) - 1.) do
for _ = 0 to min (nToGet - n - 1) (chunkSize - 1) do
let value = rnd.NextDouble()
sum <- sum + value
n <- n + 1
// bin.Write(value)
// bin.Seek(0, SeekOrigin.Begin) |> ignore
// bin.Write n
sum / float n, n
let mean, n = getResult ()
printfn $"Sample mean: {mean}, N = {n:N0}"
// The example displays output like the following:
// Sample mean: 0.500022771458399, N = 200,000,000
Imports System.IO
Module Example
Public Sub Main()
Dim result As Tuple(Of Double, Long) = GetResult()
Console.WriteLine("Sample mean: {0}, N = {1:N0}",
result.Item1, result.Item2)
End Sub
Private Function GetResult As Tuple(Of Double, Long)
Dim chunkSize As Integer = 50000000
Dim nToGet As Integer = 200000000
Dim rnd As New Random()
' Dim fs As New FileStream(".\data.bin", FileMode.Create)
' Dim bin As New BinaryWriter(fs)
' bin.Write(CInt(0))
Dim n As Integer
Dim sum As Double
For outer As Integer = 0 To CInt(Math.Ceiling(nToGet/chunkSize) - 1)
For inner = 0 To Math.Min(nToGet - n - 1, chunkSize - 1)
Dim value As Double = rnd.NextDouble()
sum += value
n += 1
' bin.Write(value)
Next
Next
' bin.Seek(0, SeekOrigin.Begin)
' bin.Write(n)
' bin.Close()
Return New Tuple(Of Double, Long)(sum/n, n)
End Function
End Module
' The example displays output like the following:
' Sample mean: 0.500022771458399, N = 200,000,000
Anda berulang kali menggabungkan string besar.
Karena string tidak dapat diubah, setiap operasi perangkaian string membuat string baru. Dampak untuk string kecil, atau untuk sejumlah kecil operasi perangkaian, dapat diabaikan. Tetapi untuk string besar atau sejumlah besar operasi perangkaian, perangkaian string dapat menyebabkan sejumlah besar alokasi memori dan fragmentasi memori, performa yang buruk, dan mungkin OutOfMemoryException pengecualian.
Saat menggabungkan string besar atau melakukan sejumlah besar operasi perangkaian, Anda harus menggunakan StringBuilder kelas alih-alih String kelas . Setelah Anda selesai memanipulasi string, konversikan StringBuilder instans menjadi string dengan memanggil StringBuilder.ToString metode .
Anda menyematkan sejumlah besar objek dalam memori.
Menyematkan sejumlah besar objek dalam memori untuk waktu yang lama dapat menyulitkan pengumpul sampah untuk mengalokasikan blok memori yang berdampingan. Jika Anda telah menyematkan sejumlah besar objek dalam memori, misalnya dengan menggunakan fixed
pernyataan di C# atau dengan memanggil GCHandle.Alloc(Object, GCHandleType) metode dengan jenis GCHandleType.Pinnedhandel , Anda dapat melakukan hal berikut untuk mengatasi OutOfMemoryException pengecualian.
Mengevaluasi apakah setiap objek benar-benar perlu disematkan,
Pastikan bahwa setiap objek tidak disematkan sesegera mungkin.
Pastikan bahwa setiap panggilan ke GCHandle.Alloc(Object, GCHandleType) metode untuk menyematkan memori memiliki panggilan yang sesuai dengan metode untuk melepas sematan memori tersebut GCHandle.Free .
Instruksi perantara Microsoft (MSIL) berikut memberikan OutOfMemoryException pengecualian:
Konstruktor
OutOfMemoryException() |
Menginisialisasi instans baru kelas OutOfMemoryException. |
OutOfMemoryException(SerializationInfo, StreamingContext) |
Kedaluwarsa.
Menginisialisasi instans OutOfMemoryException baru kelas dengan data berseri. |
OutOfMemoryException(String) |
Menginisialisasi instans OutOfMemoryException baru kelas dengan pesan kesalahan tertentu. |
OutOfMemoryException(String, Exception) |
Menginisialisasi instans OutOfMemoryException baru kelas dengan pesan kesalahan tertentu dan referensi ke pengecualian dalam yang merupakan penyebab pengecualian ini. |
Properti
Data |
Mendapatkan kumpulan pasangan kunci/nilai yang memberikan informasi tambahan yang ditentukan pengguna tentang pengecualian. (Diperoleh dari Exception) |
HelpLink |
Mendapatkan atau mengatur tautan ke file bantuan yang terkait dengan pengecualian ini. (Diperoleh dari Exception) |
HResult |
Mendapatkan atau mengatur HRESULT, nilai numerik berkode yang ditetapkan ke pengecualian tertentu. (Diperoleh dari Exception) |
InnerException |
Mendapatkan instans Exception yang menyebabkan pengecualian saat ini. (Diperoleh dari Exception) |
Message |
Mendapatkan pesan yang menjelaskan pengecualian saat ini. (Diperoleh dari Exception) |
Source |
Get dan set nama aplikasi atau objek yang menyebabkan kesalahan. (Diperoleh dari Exception) |
StackTrace |
Mendapatkan representasi string dari bingkai langsung pada tumpukan panggilan. (Diperoleh dari Exception) |
TargetSite |
Mendapatkan metode yang melemparkan pengecualian saat ini. (Diperoleh dari Exception) |
Metode
Equals(Object) |
Menentukan apakah objek yang ditentukan sama dengan objek saat ini. (Diperoleh dari Object) |
GetBaseException() |
Ketika ditimpa di kelas turunan Exception , mengembalikan yang merupakan akar penyebab dari satu atau beberapa pengecualian berikutnya. (Diperoleh dari Exception) |
GetHashCode() |
Berfungsi sebagai fungsi hash default. (Diperoleh dari Object) |
GetObjectData(SerializationInfo, StreamingContext) |
Kedaluwarsa.
Saat ditimpa di kelas turunan SerializationInfo , mengatur dengan informasi tentang pengecualian. (Diperoleh dari Exception) |
GetType() |
Mendapatkan jenis runtime dari instans saat ini. (Diperoleh dari Exception) |
MemberwiseClone() |
Membuat salinan dangkal dari saat ini Object. (Diperoleh dari Object) |
ToString() |
Membuat dan mengembalikan representasi string dari pengecualian saat ini. (Diperoleh dari Exception) |
Acara
SerializeObjectState |
Kedaluwarsa.
Terjadi ketika pengecualian diserialisasikan untuk membuat objek status pengecualian yang berisi data berseri tentang pengecualian. (Diperoleh dari Exception) |