ฉันกำลังตอบแท็กlinux คำตอบของฉันเฉพาะกับLinuxเท่านั้น
ใช่หน้าเว็บขนาดใหญ่มีแนวโน้มที่จะกระจายตัว มีสองมุมมองของหน่วยความจำกระบวนการที่คุณได้รับ (เสมือน) และมุมมองที่เคอร์เนลจัดการ (จริง) ยิ่งหน้าใหญ่เท่าใดก็ยิ่งเป็นการยากที่จะจัดกลุ่ม (และเก็บไว้) กับเพื่อนบ้านโดยเฉพาะอย่างยิ่งเมื่อบริการของคุณกำลังทำงานบนระบบที่ต้องให้การสนับสนุนผู้อื่นด้วยโดยค่าเริ่มต้นจัดสรรและเขียนไปยังหน่วยความจำมากกว่า ท้ายที่สุดใช้งานจริง
การแมปเคอร์เนลของที่อยู่ที่ได้รับ (ของจริง) เป็นส่วนตัว มีเหตุผลที่ดีมากที่ userspace มองพวกเขาในขณะที่เคอร์เนลแสดงพวกเขาเนื่องจากเคอร์เนลจำเป็นต้องสามารถ overcommit โดยไม่ทำให้ผู้ใช้สับสน กระบวนการของคุณได้รับพื้นที่ที่อยู่"Disneyfied"ที่ดีต่อเนื่องซึ่งใช้งานได้โดยไม่สนใจว่าสิ่งที่เคอร์เนลทำกับหน่วยความจำนั้นอยู่เบื้องหลัง
เหตุผลที่คุณเห็นประสิทธิภาพลดลงในเซิร์ฟเวอร์ที่ใช้งานมานานน่าจะเป็นเพราะบล็อกที่จัดสรรซึ่งไม่ได้ล็อคอย่างชัดเจน (เช่นmlock()
/ mlockall()
หรือposix_madvise()
) และไม่ได้รับการแก้ไขในระยะเวลาหนึ่งซึ่งได้ถูกเพจเอาต์ซึ่งหมายความว่าบริการของคุณ พวกเขา การแก้ไขพฤติกรรมนี้ทำให้กระบวนการของคุณเป็นเพื่อนบ้านที่ไม่ดีซึ่งเป็นสาเหตุที่หลายคนใส่ RDBMS ไว้ในเซิร์ฟเวอร์ที่แตกต่างจากเว็บ / php / python / ruby / อะไรก็ตาม วิธีเดียวที่จะแก้ไขปัญหานี้ได้คือการลดการแข่งขันสำหรับบล็อกที่ต่อเนื่องกัน
การแตกแฟรกเมนต์สามารถสังเกตเห็นได้จริง ๆ เท่านั้น (ในกรณีส่วนใหญ่) เมื่อเพจ A อยู่ในหน่วยความจำและเพจ B ย้ายไปสลับ โดยปกติแล้วการเริ่มต้นบริการของคุณอีกครั้งดูเหมือนจะ 'รักษา' สิ่งนี้ แต่เพียงเพราะเคอร์เนลยังไม่ได้มีโอกาสหน้ากระบวนการออก '(ตอนนี้) บล็อกที่จัดสรรใหม่ภายในขอบเขตอัตราส่วน overcommit
ในความเป็นจริงการเริ่มต้นใหม่ (สมมติว่า) 'apache' ภายใต้ภาระสูงมีแนวโน้มที่จะส่งบล็อกที่เป็นเจ้าของโดยบริการอื่น ๆ ตรงไปยังดิสก์ ดังนั้นใช่ 'apache' จะดีขึ้นในช่วงเวลาสั้น ๆ แต่ 'mysql' อาจประสบ .. อย่างน้อยก็จนกว่าเคอร์เนลจะทำให้พวกเขามีปัญหาเท่ากันเมื่อไม่มีหน่วยความจำกายภาพเหลือเฟือ
เพิ่มหน่วยความจำเพิ่มเติมหรือแยกกันตามความต้องการของmalloc()
ผู้บริโภค :) ไม่ใช่เพียงแค่การแยกส่วนที่คุณต้องมอง
ลองvmstat
ดูภาพรวมของสิ่งที่ถูกจัดเก็บไว้ที่ใด