การส่งคืนอิมเมจ base64 โดยไม่มีหน่วยความจำรั่ว ASP.NET MVC 3

ฉันมีรูปภาพบางรูปเก็บไว้ในฐานข้อมูลเป็นสตริง base64 และจำเป็นต้องส่งคืนรูปภาพเหล่านั้นจากตัวควบคุม MVC ฉันจะทำอย่างไรโดยไม่มีหน่วยความจำรั่ว?

ก่อนหน้านี้ฉันใช้สิ่งนี้:

return File(Convert.FromBase64String(pictureString), "image/jpeg");

อย่างไรก็ตาม กระบวนการ w3wp จะเริ่มใช้หน่วยความจำจำนวนมากสำหรับรูปภาพบางรูป

มีวิธีที่เหมาะสมในการทำเช่นนี้หรือไม่? ขณะนี้ฉันได้ตัดสินใจเพียงตั้งค่าแต่ละภาพเป็น data:image/jpg;base64,string_here และมันใช้หน่วยความจำน้อยกว่ามาก .. แต่ดูเหมือนว่าจะโหลดหน้าเว็บได้ช้ากว่ามากเช่นกัน

ความช่วยเหลือใด ๆ ที่ชื่นชม


person chemicalNova    schedule 20.09.2011    source แหล่งที่มา
comment
รูปภาพของคุณใหญ่แค่ไหน เช่น สตริงที่เข้ารหัส base 64 และ JPEG มีความยาวเท่าใด   -  person Codo    schedule 20.09.2011


คำตอบ (2)


+1 ถึงความคิดเห็นของ Darin Dimitrov

หากรูปภาพ / ข้อมูลที่เข้ารหัส base64 มากกว่า 85K จะถูกจัดสรรบน LOH (ฮีปวัตถุ lage) GC สำหรับการจัดสรรดังกล่าวมีราคาแพงกว่าเนื่องจากต้องรอการรวบรวมรุ่นที่ 2

อีกวิธีหนึ่งหากคุณต้องใช้อิมเมจที่เข้ารหัส base64 ต่อไปคือการใช้สตรีมของคุณเองที่อ่านข้อมูลจากค่าที่เข้ารหัส Base64 เป็นชิ้น ๆ เพื่อหลีกเลี่ยงการจัดสรรบล็อกหน่วยความจำขนาดใหญ่ที่สอง หากคุณสามารถอ่านสตริงเป็นชิ้นได้ คุณจะสามารถหลีกเลี่ยงการจัดสรรอ็อบเจ็กต์บน LOH และอาจเพียงแค่นำบัฟเฟอร์ขนาดเล็กกลับมาใช้ซ้ำเพื่ออ่าน/ถอดรหัส

person Alexei Levenkov    schedule 20.09.2011
comment
ขอขอบคุณสำหรับข้อมูล. ฉันได้ทำเครื่องหมายว่านี่คือคำตอบเนื่องจากมีการโหลดรูปภาพที่มีขนาดใหญ่กว่า 85k ตั้งแต่นั้นมาฉันต้องเขียนแอปพลิเคชันทั้งหมดใหม่ (ฉันไม่ได้เขียนขึ้นต้นด้วย :/) ขอบคุณสำหรับคำแนะนำทั้งหมด! - person chemicalNova; 13.10.2011

ก่อนหน้านี้ฉันใช้สิ่งนี้:

ไม่มี การรั่วไหล ในโค้ดนี้ ปัญหาคือมันโหลดรูปภาพทั้งหมดในหน่วยความจำก่อนที่จะสตรีมไปยังการตอบสนอง หน่วยความจำทำให้คุณสังเกตเห็นว่ากระบวนการ w3p เป็นเรื่องปกติ และเมื่อ Garbage Collector เริ่มทำงาน มันจะทำความสะอาด คุณไม่ควรกังวลเรื่องนี้จริงๆ เว้นแต่คุณจะแสดงภาพขนาดใหญ่บางภาพ

ปัญหาในการออกแบบของคุณคือคุณใช้ base64 ซึ่งหมายความว่าคุณต้องโหลดเนื้อหาทั้งหมดก่อนจึงจะสามารถถอดรหัสกลับเป็นอาร์เรย์ไบต์ได้ อีกวิธีหนึ่งคือจัดเก็บรูปภาพเป็นข้อมูลดิบในฐานข้อมูลของคุณ จากนั้นใช้สตรีมเพื่ออ่านเป็นส่วนๆ และเขียนส่วนเหล่านั้นทันทีเพื่อตอบกลับ วิธีนี้เฉพาะ ชิ้น ที่กำลังประมวลผลเท่านั้นจึงจะถูกโหลดลงในหน่วยความจำ ณ เวลาที่กำหนด

อีกแนวทางหนึ่งที่ฉันอาจแนะนำให้คุณคือไม่จัดเก็บรูปภาพในฐานข้อมูลเลย แต่เก็บไว้ในระบบไฟล์และจัดเก็บเฉพาะเส้นทางไปยังรูปภาพในฐานข้อมูลเท่านั้น จากนั้นในการดำเนินการกับคอนโทรลเลอร์ของคุณ สิ่งที่คุณต้องทำคือ return File(pathToTheImage, "image/jpeg")

เพื่อเป็นการเพิ่มประสิทธิภาพเพิ่มเติม หากรูปภาพเหล่านั้นไม่เปลี่ยนแปลงบ่อยครั้ง คุณสามารถเพิ่มการแคชเอาต์พุตที่เหมาะสมให้กับการทำงานของคอนโทรลเลอร์ที่ให้บริการรูปภาพเหล่านั้นเพื่อหลีกเลี่ยงไม่ให้โดนกระทบทุกครั้ง

person Darin Dimitrov    schedule 20.09.2011
comment
ขอบคุณสำหรับข้อเสนอแนะของคุณ.. พวกเขาช่วยฉันได้อย่างแน่นอนในขณะที่เขียนใบสมัครใหม่! - person chemicalNova; 13.10.2011