Những lợi thế của việc thiết lập LargeHeap thành đúng là gì?


122

Tôi có một Ứng dụng với gần 50 lớp tôi đang cài đặt android:largeHeap="true", như có thể thấy bên dưới. Đây có phải là một thực hành tốt?

<application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="Mall"
        android:largeHeap="true"
        android:logo="@drawable/logo_for_up"
        android:screenOrientation="portrait"
        android:theme="@style/AppTheme" >
</application>

Vui lòng đề xuất những lợi thế và bất lợi cho việc sử dụng nó.

Tôi nhận được vấn đề bộ nhớ đó là lý do tại sao tôi hỏi câu hỏi này.


nếu bạn cần bộ nhớ lớn cho ứng dụng của mình như trò chơi 3dmodels, v.v.
januprasad

47
50 lớp không phải là nhiều.
Chris Hayes


nếu bạn đang sử dụng một số dịch vụ hoặc bất kỳ ứng dụng ứng dụng nào khác trong ứng dụng tiêu thụ bộ nhớ thì ứng dụng của bạn sẽ gặp vấn đề về bộ nhớ như máy ảnh là vấn đề phổ biến nhất của nhà phát triển trong khi sử dụng ứng dụng hoặc nếu bạn có nhiều biến số gây tốn bộ nhớ hoặc tĩnh biến cũng có thể là lý do cho điều đó.
Aditi

4
Số lượng các lớp học không quan trọng. Những gì thường mất rất nhiều bộ nhớ là bitmap. Xem " Tải phiên bản thu nhỏ vào bộ nhớ ".
ToolmakerSteve

Câu trả lời:


116

Quá muộn cho bữa tiệc ở đây, nhưng tôi sẽ cung cấp 0,02 $ dù sao đi nữa.
Đây không phải là một ý tưởng tốt để sử dụng android:largeHeap="true" đây là trích xuất từ ​​google giải thích nó,

Tuy nhiên, khả năng yêu cầu một đống lớn chỉ dành cho một bộ ứng dụng nhỏ có thể biện minh cho nhu cầu tiêu thụ nhiều RAM hơn (chẳng hạn như một ứng dụng chỉnh sửa ảnh lớn). Không bao giờ yêu cầu một đống lớn đơn giản vì bạn đã hết bộ nhớ và bạn cần sửa chữa nhanh chóng, bạn chỉ nên sử dụng nó khi bạn biết chính xác nơi tất cả bộ nhớ của bạn được phân bổ và tại sao nó phải được giữ lại. Tuy nhiên, ngay cả khi bạn tự tin rằng ứng dụng của bạn có thể biện minh cho đống lớn, bạn nên tránh yêu cầu nó ở bất kỳ mức độ nào có thể. Việc sử dụng bộ nhớ thêm sẽ ngày càng gây hại cho trải nghiệm người dùng nói chung vì việc thu gom rác sẽ mất nhiều thời gian hơn và hiệu suất hệ thống có thể chậm hơn khi chuyển đổi tác vụ hoặc thực hiện các hoạt động chung khác.

đây là liên kết đầy đủ của tài liệu https://developer.android.com/training/articles/memory.html

CẬP NHẬT

Sau khi làm việc hết sức với out of memory errorstôi, tôi sẽ nói thêm điều này vào bảng kê khai để tránh vấn đề oom không phải là một tội lỗi, cũng như @Milad chỉ ra bên dưới nó không ảnh hưởng đến hoạt động bình thường của ứng dụng

CẬP NHẬT 2

Dưới đây là một vài lời khuyên để đối phó vớiout of memory errors

1) Sử dụng các callback mà android cho onLowMemory, onTrimMemory(int) và xóa bộ nhớ cache của hình ảnh tương tự (picasso, lướt, ngoài trời ....), bạn có thể đọc thêm về họ ở đâyở đây
2) nén tập tin của bạn (hình ảnh, pdf)
3) đọc về Làm thế nào để xử lý bitmap hiệu quả hơn ở đây
4) Sử dụng lint thường xuyên trước khi đẩy sản xuất để đảm bảo mã đẹp và không cồng kềnh


1
Tại sao bạn nói "nó không ảnh hưởng đến hoạt động bình thường của ứng dụng"? Câu trả lời này thảo luận về một số hậu quả. Ở những nơi khác, tôi đã thấy thời gian thậm chí còn tệ hơn được đo cho LargeHeap GC trên một số ứng dụng.
ToolmakerSteve

59

Tôi nghĩ rằng đây là một câu hỏi rất hiệu quả, và hãy để tôi thêm một số chi tiết về ưu điểm và nhược điểm của việc sử dụng tùy chọn này.

Những gì bạn nhận được:

  • Rõ ràng, bạn nhận được đống lớn hơn, có nghĩa là giảm nguy cơ OutOfMemoryError.

Những gì bạn mất:

  • Bạn có thể mất một số khung hình, điều này có thể gây ra hiện tượng quá giang . Heap lớn hơn làm cho bộ sưu tập rác mất nhiều thời gian hơn. Bởi vì bộ thu gom rác về cơ bản phải đi qua toàn bộ bộ đối tượng sống của bạn. Thông thường, thời gian tạm dừng thu gom rác là khoảng 5ms và bạn có thể nghĩ vài mili giây không phải là vấn đề lớn. Nhưng mỗi mili giây. Thiết bị Android phải cập nhật màn hình của nó sau mỗi 16 ms và thời gian GC dài hơn có thể đẩy thời gian xử lý khung hình của bạn vượt qua rào cản 16 mili giây, điều này có thể gây ra hiện tượng quá giang.

  • Ngoài ra các ứng dụng chuyển đổi sẽ trở nên chậm hơn . Hệ thống Android có thể tiêu diệt các tiến trình trong bộ nhớ cache LRU bắt đầu bằng quy trình ít được sử dụng gần đây nhất, nhưng cũng đưa ra một số xem xét về quy trình nào chiếm nhiều bộ nhớ nhất. Vì vậy, nếu bạn sử dụng heap lớn hơn, quy trình của bạn sẽ có nhiều khả năng bị giết khi nền, điều đó có nghĩa là có thể mất nhiều thời gian hơn khi người dùng muốn chuyển từ các ứng dụng khác sang ứng dụng của bạn. Ngoài ra, các quy trình nền khác sẽ có nhiều khả năng bị loại bỏ khi quy trình của bạn được tạo nền trước, vì ứng dụng của bạn yêu cầu bộ nhớ lớn hơn. Nó có nghĩa là chuyển từ ứng dụng của bạn sang các ứng dụng khác cũng mất nhiều thời gian hơn.

Phần kết luận :

Tránh sử dụng largeHeaptùy chọn càng nhiều càng tốt. Nó có thể khiến bạn giảm chi phí hiệu suất khó nhận thấy và trải nghiệm người dùng xấu.


17

Tôi có một ứng dụng với gần 50 lớp

Tôi không nghĩ rằng điều này làm cho nhiều vấn đề. Lý do tại sao bạn gặp phải lỗi outOfMemory thường là tải quá nhiều hình ảnh trong ứng dụng của bạn hoặc đại loại như thế. Nếu bạn không hài lòng khi sử dụng heap lớn, bạn phải tìm cách tối ưu hóa bằng bộ nhớ.

Bạn cũng có thể sử dụng Thư viện tải hình ảnh như Picasso , UIL hoặc Glide . Tất cả chúng đều có tính năng lưu trữ hình ảnh trong bộ nhớ và / hoặc trên đĩa.


1
để tải hình ảnh, tôi thường khuyên dùng picaso hoặc trình tải hình ảnh phổ quát
Mightian

5
Glide tốt hơn và được tối ưu hóa hơn một chút sau đó Picasso
Damien Praca

1
@DamienPraca Tôi không nghĩ vậy, ít nhất là nếu bạn sử dụng đúng các thẻ (setTag (), pauseTag (), CVTag ()) trong Picasso.
Ruslan Berozov

15

Trên thực tế android: LargeHeap là công cụ để tăng bộ nhớ được phân bổ của bạn cho ứng dụng.

Không có định nghĩa rõ ràng về nhu cầu sử dụng cờ này. Nếu bạn cần thêm bộ nhớ - Android cung cấp cho bạn một công cụ để tăng nó. Nhưng sự cần thiết của việc sử dụng, bạn xác định chính mình.


4
vâng, có một định nghĩa rõ ràng giới thiệu liên kết này developer.android.com/training/articles/memory.html
Mightian

2
@war_Hero - có lẽ bài báo đó đã thay đổi nội dung của nó? Không có đề cập đến bigHeap trong đó.
ToolmakerSteve

7

Nếu bạn phải sử dụng (và giữ lại) một lượng lớn bộ nhớ, thì có, bạn có thể và nên sử dụng android:largeHeap="true". Nhưng nếu bạn sử dụng nó, bạn nên chuẩn bị để ứng dụng của bạn bị xóa khỏi bộ nhớ mỗi khi các ứng dụng khác ở phía trước.

Bằng cách "chuẩn bị", ý tôi là bạn nên thiết kế theo khả năng đó, để các phương thức onStop()onResume()phương thức của bạn được viết hiệu quả nhất có thể, đồng thời đảm bảo rằng tất cả trạng thái thích hợp được lưu và khôi phục theo cách thể hiện diện mạo liền mạch cho người dùng.

Có ba phương pháp có liên quan đến thông số này: maxMemory(), getMemoryClass(), và getLargeMemoryClass().

Đối với hầu hết các thiết bị, maxMemory()sẽ biểu thị một giá trị tương tự getMemoryClass()theo mặc định, mặc dù cái sau được biểu thị bằng megabyte, trong khi cái trước được biểu thị bằng byte.

Khi bạn sử dụng largeHeaptham số, maxMemory()sẽ được tăng lên mức cao hơn dành riêng cho thiết bị, trong khi getMemoryClass()sẽ giữ nguyên.

getMemoryClass()không giới hạn kích thước heap của bạn, nhưng nó cho bạn biết số lượng heap bạn nên sử dụng nếu bạn muốn ứng dụng của mình hoạt động thoải máitương thích trong giới hạn của thiết bị cụ thể mà bạn đang chạy.

maxMemory(), ngược lại, sẽ hạn chế kích thước heap của bạn và do đó bạn có quyền truy cập vào heap bổ sung thông qua việc tăng giá trị của nó và largeHeaptăng giá trị đó. Tuy nhiên, lượng heap tăng vẫn còn hạn chế và giới hạn đó sẽ dành riêng cho thiết bị, điều đó có nghĩa là lượng heap có sẵn cho ứng dụng của bạn sẽ thay đổi, tùy thuộc vào tài nguyên của thiết bị mà ứng dụng của bạn đang chạy. Vì vậy, việc sử dụng largeHeapkhông phải là một lời mời để ứng dụng của bạn từ bỏ tất cả sự thận trọng và tìm đường đi qua bữa tiệc buffet hoàn toàn có thể ăn.

Ứng dụng của bạn có thể khám phá chính xác dung lượng bộ nhớ sẽ được cung cấp trên một thiết bị cụ thể thông qua việc sử dụng largeHeaptham số bằng cách gọi phương thức getLargeMemoryClass(). Giá trị được trả về là megabyte.

Bài đăng trước đó bao gồm một cuộc thảo luận về largeHeaptham số, cũng như một số ví dụ về số lượng heap được cung cấp có và không có việc sử dụng nó, trên một số thiết bị Android cụ thể:

Phát hiện kích thước heap ứng dụng trong Android

Tôi chưa triển khai bất kỳ ứng dụng nào của riêng mình với thông số này được đặt thành đúng. Tuy nhiên, tôi có một số mã sử dụng nhiều bộ nhớ trong một trong các ứng dụng của mình để biên dịch một tập hợp các tham số liên quan đến tối ưu hóa, chỉ chạy trong quá trình phát triển. Tôi chỉ thêm largeHeaptham số trong quá trình phát triển, để tránh lỗi bộ nhớ trong khi chạy mã này. Nhưng tôi xóa tham số (và mã) trước khi triển khai ứng dụng.


1
"từ bỏ tất cả các cảnh báo và ỉn theo cách của mình thông qua tất cả các-bạn-có thể ăn buffet" 😂
Joshua Pinter

4

Liệu các quy trình của ứng dụng của bạn có nên được tạo ra với một đống Dalvik lớn hay không. Điều này áp dụng cho tất cả các quy trình được tạo cho ứng dụng. Nó chỉ áp dụng cho ứng dụng đầu tiên được tải vào một quy trình; nếu bạn đang sử dụng ID người dùng chung để cho phép nhiều ứng dụng sử dụng một quy trình, tất cả họ phải sử dụng tùy chọn này một cách nhất quán nếu không họ sẽ có kết quả không thể đoán trước.

Hầu hết các ứng dụng không cần điều này và thay vào đó nên tập trung vào việc giảm mức sử dụng bộ nhớ chung để cải thiện hiệu suất. Kích hoạt tính năng này cũng không đảm bảo tăng cố định bộ nhớ khả dụng, vì một số thiết bị bị hạn chế bởi tổng bộ nhớ khả dụng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.