2012-12-19 23 views
17

Tôi vừa thừa hưởng một trang web có tập lệnh PHP luôn chạy hết bộ nhớ ở mức 117 MB. Điều này xảy ra ngay cả khi tôi tăng biến memory_limit của PHP lên 312 MB, mà tôi đang thực hiện thông qua php.ini.Lỗi hết bộ nhớ PHP mặc dù memory_limit không đạt được

Điều này hiện được giải quyết nhờ có một đầu mối tuyệt vời từ pcguru. Xem câu trả lời của tôi dưới đây bắt đầu: tôi cuối cùng đã tìm thấy câu trả lời

ini_get('memory_limit') trả về giá trị thiết lập trong php.ini, vì vậy tôi chắc chắn Apache đã khởi động lại sau khi thay đổi giá trị. Tôi đang sử dụng memory_get_usage(true) để trả lại bộ nhớ được tiêu thụ bởi tập lệnh tại các điểm khác nhau trên đường đi. Và nó liên tục thất bại khi nó đạt đến 117 MB.

Có một số giới hạn PHP nội bộ mà tôi không biết rằng nó có bao giờ phân bổ hơn 117MB cho một tập lệnh riêng lẻ không?

Máy chủ có RAM 1 GB và đang chạy CentOS. Tôi có quyền truy cập trình bao gốc. PHP là phiên bản 5.3.18. MySQL là phiên bản 5.1.66-cll.

Tập lệnh này nằm sau tên người dùng/mật khẩu và tôi không thể cung cấp quyền truy cập công khai vào nó.

Đã chỉnh sửa để thêm:

1) Cảm ơn tất cả sự giúp đỡ của bạn cho đến nay. Bạn sẽ tìm thấy thêm thông tin trong các trả lời của tôi cho các nhận xét của người dùng cụ thể theo các câu trả lời khác nhau bên dưới.

2) Suhosin chắc chắn chưa được cài đặt. Tôi đã kiểm tra ở nhiều nơi bao gồm chạy một tập lệnh và kiểm tra các hằng số và chạy php -v

3) Nhật ký apache không có bản ghi của thông báo lỗi cụ thể mà tôi nhận được. Ghi nhật ký được bật trong php.ini. Tôi đường ống qua grep để tìm kiếm toàn bộ nhật ký.

4) Có thể xảy ra lỗi sai trong trường hợp này không?

+9

Lỗi chính xác mà bạn thấy là gì? Có lẽ bạn đang bối rối bởi "cố gắng phân bổ xxx byte" –

+4

Kudo để có phiên bản PHP 5.3 cập nhật. –

+2

Bạn có miếng dán suhosin nào không? – DaveRandom

Trả lời

17

Tôi cuối cùng đã tìm thấy câu trả lời. Các đầu mối đến từ câu trả lời của pcguru bắt đầu 'Vì máy chủ chỉ có 1 GB RAM ...'.

Trên linh cảm, tôi đã xem xét liệu Apache có giới hạn bộ nhớ riêng của mình hay không vì chúng có khả năng ảnh hưởng đến khả năng phân bổ bộ nhớ của PHP. Ngay ở đầu httpd.conf tôi tìm thấy tuyên bố này: RLimitMEM 204535125

Điều này được đặt ở đó bằng whm/cpanel. Theo sau trang web WHM/cPanel không đúng cách tính toán giá trị của nó trên một máy chủ ảo ... http://forums.jaguarpc.com/vps-dedicated/17341-apache-memory-limit-rlimitmem.html

Kịch bản chạy ra khỏi bộ nhớ được hầu hết các cách thức thông qua, vì vậy tôi tăng RLimitMEM đến 268.435.456 (256 MB) và chạy lại kịch bản. Nó hoàn thành việc hợp nhất mảng và tạo tệp csv để tải xuống.

ETA: Sau khi đọc thêm về RLimitMEM và RLimitCPU, tôi quyết định xóa chúng khỏi httpd.conf. Điều này cho phép ini_set ('memory_limit', '### M') hoạt động, và bây giờ tôi cung cấp cho kịch bản cụ thể bộ nhớ bổ sung cần thiết. Tôi cũng tăng gấp đôi RAM trên máy chủ đó.

Cảm ơn tất cả mọi người đã giúp bạn phát hiện vấn đề này, và đặc biệt là với pcguru, người đã đưa ra đầu mối quan trọng đã đưa tôi đến giải pháp.

1

Đây có thể không phải là câu trả lời cho vấn đề của bạn, nhưng nếu bạn chạy PHP từ dòng lệnh, bạn có thể ghi đè giới hạn bộ nhớ từ php.ini.

php -d memory_limit=321M my_script.php 

Tôi không chắc chắn giới hạn bộ nhớ mặc định qua cli là gì.

Ngoài ra, bạn có thể chạy php --ini và kiểm tra kết quả.

+0

php --ini trả về: Tệp Cấu hình (php.ini) Đường dẫn:/usr/local/lib Cấu hình được tải Tệp: /usr/local/lib/php.ini Quét để tìm các tệp .ini bổ sung trong: (none) Các tệp .ini bổ sung được phân tích cú pháp: (không) – user8109

+0

Ngoài ra - tôi không thể chạy tập lệnh từ lời nhắc vì phần bị treo đòi hỏi một số biến bài đăng. Thật không may nó khá phức tạp, sử dụng mảng lớn vì lý do mà không có ý nghĩa với tôi. Theo quan điểm của tôi, nó nên sử dụng các bảng tạm thời và chỉ gửi kết quả cuối cùng tới PHP. Nhưng trong khi chờ đợi, nếu tôi có thể cho nó 198MB nó sẽ hoàn thành, đó là một sửa chữa tạm thời hữu ích. – user8109

+0

Hiểu điều đó. Hành vi thực sự kỳ lạ. – aebersold

-5

Bạn có vòng lặp vô hạn ở đâu đó trong mã của mình.

+2

Bạn có thể nói như thế nào mà không cần nhìn vào mã. Đó là một dự đoán tốt nhất mà không nên được đăng như là một câu trả lời. – webnoob

+0

Nếu tăng giới hạn bộ nhớ không giúp đây là thứ thứ hai có thể gây ra loại lỗi này. Bất cứ ai cũng có thể thử nó với một vòng lặp vô hạn hoặc với một chức năng đệ quy xấu. –

+0

Nó không phải là một vòng lặp vô hạn. Điều đó đòi hỏi một mảng vô hạn! Nó liên tục bị rơi ở mức 117MB mặc dù (được cho là) ​​có nhiều RAM hơn. Hơn nữa, vòng lặp trong đó sự cố xảy ra là làm một hợp nhất mảng. Mỗi lần lặp lại nibbles khoảng 79 byte. – user8109

2

Đây không phải là một câu trả lời cho lý do tại sao kịch bản của bạn đang hấp hối sau một sử dụng bộ nhớ nhất định, nhưng bạn có thể khắc phục nó bằng cách loại bỏ giới hạn bộ nhớ hoàn toàn trong kịch bản PHP bản thân:

ini_set('memory_limit', '-1'); 

Đây là nguy hiểm. Nếu bạn có một kịch bản chạy trốn, PHP sẽ mất bộ nhớ cho đến khi máy chủ của bạn không còn gì để phân bổ và rơi xuống. Vì vậy, bạn chỉ nên sử dụng điều này nếu bạn đang chắc chắn chính kịch bản đó không phải là vấn đề và chỉ để kiểm tra đầu ra.

Như thế nào nếu PHP có một số giới hạn cho mỗi tập lệnh khi sử dụng bộ nhớ, không. Tôi đã chạy các tập lệnh cá nhân với mức sử dụng bộ nhớ gần 1GB.

+0

Cảm ơn M_user. Tôi không thể chạy nguy cơ đưa ra lệnh gọi-blanch PHP. Các trang web của khách hàng được truy cập quốc tế để không có thời gian ngừng hoạt động thuận tiện. Hữu ích khi biết PHP không áp đặt giới hạn - cảm ơn vì điều đó. Có thể lỗi được báo cáo không? – user8109

+0

Mọi thứ đều có thể. Thông báo lỗi thực sự là gì? –

8

Vì máy chủ chỉ có 1 GB RAM, tôi đang hướng đến khả năng bạn đã thực sự hết bộ nhớ hệ thống.

See this thread. Bạn nhận được cùng một "PHP Fatal error: Out of memory" thay vì phổ biến hơn "Fatal error: Allowed memory size of ...". Lỗi của bạn cho biết hệ thống không thể cấp phát bộ nhớ nhiều hơn, nghĩa là ngay cả các hàm nội bộ của PHP cũng không thể cấp phát bộ nhớ nhiều hơn, hãy để một mình mã của riêng bạn.

PHP được định cấu hình để chạy với Apache như thế nào? Là một mô-đun hoặc như CGI? Bạn có thể chạy bao nhiêu tiến trình PHP cùng một lúc? Bạn có không gian trao đổi không?

Nếu bạn sử dụng PHP làm mô-đun trong Apache, Apache có thói quen khó chịu về việc lưu giữ bộ nhớ mà quy trình PHP được cấp phát. Đoán vì nó không thể khởi động lại mô-đun PHP trong công nhân, chỉ cần khởi động lại toàn bộ nhân viên. Mỗi công nhân đã phục vụ PHP chỉ đơn giản là phát triển đến giới hạn bộ nhớ PHP theo thời gian khi nhân viên đó phục vụ một tập lệnh phân bổ rất nhiều RAM. Vì vậy, nếu bạn có nhiều công nhân cùng một lúc, mỗi người sử dụng 100 MB +, bạn sẽ nhanh chóng hết RAM. Hãy thử giới hạn số lượng nhân viên đồng thời trong Apache.

+0

Cảm ơn pcguru - điều này có ý nghĩa và phù hợp với các sự kiện. Để trả lời các câu hỏi của bạn: PHP được chạy như một mô-đun. Có không gian trao đổi có sẵn và đang được sử dụng - đó là một máy chủ ảo chạy 8 trang web. Có một số bảng DB lớn - lớn nhất có 2,4 triệu bản ghi.Có rất nhiều khách truy cập trang web và báo cáo này là một trong số hàng tá nhân viên của họ có thể đang chạy. Lời giải thích của bạn cũng trả lời một câu đố khác, đó là lý do tại sao báo cáo thành công trong những giờ nhỏ của đêm hôm trước (khi tôi nghĩ rằng tôi đã khắc phục được vấn đề :-). Tôi sắp xem nó chạy với đầu trong một cửa sổ khác. – user8109

+0

chạy trên cùng cho thấy hệ thống không chạy hết RAM vật lý trong khi truy vấn đang chạy. Nó giảm xuống còn khoảng 60MB ngay trước khi bị rơi, nhưng vẫn có 1.6GB không gian hoán đổi. Đây là một gợi ý tuyệt vời và nó có thể dẫn tôi đến câu trả lời thực sự, vì vậy cảm ơn vì điều đó. Tôi chỉ đang thử nghiệm bây giờ. – user8109

+1

Thật tuyệt khi nghe, có nhiều cách để giảm mức sử dụng bộ nhớ với Apache/PHP nhưng nó thường đi kèm với hiệu năng thấp hơn. Tôi hy vọng bạn làm cho nó hoạt động. Nếu không, người ta luôn có thể mua thêm RAM cho máy chủ. :) – oldwizard

Các vấn đề liên quan