-
Vì tất cả mã code của chúng tôi đều
chạy rất nhanh và tuyệt vời, hãy
-
nói thêm một chút về bộ nhớ và cách nó
ảnh hưởng đến hiệu suất trong hệ thống.
-
Nhiều ngôn ngữ lập trình được biết đến
là gần với phần cứng,
-
hay đúng hơn là hiệu suất cao,
như C, C ++,
-
và Fortran, thông thường bản thân các
lập trình viên tự quản lý các bộ nhớ.
-
Thực ra các lập trình viên
chịu trách nhiệm cho việc
-
phân bổ một khối bộ nhớ và nhiều khi
là giải phóng nó trong tương lai
-
khi họ đã thực sự sử dụng xong.
-
Vì bạn xác định khi nào và bao nhiêu
bộ nhớ được phân bổ trống nên toàn bộ
-
chất lượng quản lý bộ nhớ phụ thuộc
vào kỹ năng và hiệu quả của bạn.
-
Đó đúng là một trách nhiệm lớn.
-
Và các lập trình viên thực tế không
luôn làm tốt việc theo dõi
-
từng mảnh bộ nhớ như vậy.
-
Tôi muốn nói, hãy nghĩ rằng phát triển
sản phẩm là quá trình
-
hỗn độn và rối loạn mà bộ nhớ kết thúc
nhưng thường không giải phóng đúng cách.
-
Những khối bộ nhớ chưa được giải phóng
này gọi là các lỗ hổng bộ nhớ, chúng nằm
-
quanh các tài nguyên bị tiêu hao nơi bạn
có thể tận dụng tốt hơn hoặc ở đâu đó.
-
Để giảm sự hỗn loạn, căng thẳng và
đôi khi là tổn thất lớn về tiền bạc
-
gây ra bởi lỗ hổng bộ nhớ, các ngôn ngữ
bộ nhớ có quản lý đã được tạo ra.
-
Những thời gian chạy của các ngôn ngữ này
sẽ theo dõi việc phân bổ bộ nhớ và
-
giải phóng bộ nhớ trở lại hệ thống
khi nó không còn cần thiết với
-
chính ứng dụng đó, tất cả không cần tới
bất kỳ can thiệp nào của lập trình viên.
-
Nghệ thuật, hay đúng hơn là khoa học dành
lại bộ nhớ trong một môi trường bộ nhớ có
-
quản lý được gọi là garbage collection,
-
khái niệm được John McCarthy
nghĩ ra vào năm 1959
-
nhằm giải quyết các vấn đề
trong ngôn ngữ lập trình lisp.
-
Có các nguyên tắc cơ bản của
garbage collection như sau, đầu tiên là
-
tìm đối tượng dữ liệu của chương trình
không thể truy cập trong tương lai,
-
bất kỳ bộ nhớ nào
không còn được tham chiếu bởi bản mã.
-
Và thứ hai là dành lại các tài nguyên
được sử dụng bởi những đối tượng này.
-
Khái niệm đơn giản về lý thuyết nhưng
sẽ khá phức tạp khi bạn có tới
-
2 triệu dòng mã code và
bốn gigs worth phải phân bổ.
-
Giờ hãy nghĩ về nó, garbage collection
có thể rất nổi trội, ý tôi là,
-
nếu bạn đã có khoảng 20.000 phân bổ
trong chương trình của mình lúc này.
-
Cái nào không còn cần thiết nữa?
-
Hoặc thậm chí là khi nào bạn cần
tiến hành một lệnh garbage collection để
-
giải phóng bộ nhớ không còn được sử dụng?
-
Đây thực sự là những
câu hỏi rất khó, và
-
rất may mắn chúng tôi đã có khoảng 50 năm
đổi mới để cải thiện chúng,
-
đó là lý do garbage collector
trong Android's Runtime
-
thực sự đã phức tạp hơn một chút
so với đề xuất ban đầu của McCarthy.
-
Nó được xây dựng để nhanh chóng và
không thể xâm nhập hết mức có thể.
-
Các khối bộ nhớ trong thời gian chạy của
androids được chia khoảng hiệu quả
-
dựa vào loại phân bổ và
-
cách tốt nhất mà hệ thống có thể tổ chức
phân bổ các sự kiện GC trong tương lai.
-
Là một đối tượng mới được phân bổ,
-
những đặc điểm đó được đưa vào sao cho
phù hợp nhất với không gian dành cho nó
-
tùy theo loại phiên bản thời gian chạy
của android mà bạn đang sử dụng.
-
Và đây là một nội dung quan trọng.
-
Dù mỗi khoảng có một kích thước cài đặt
-
khi đối tượng được phân bổ, chúng tôi vẫn
theo dõi các kích thước tổng hợp và
-
khi một không gian bắt đầu phát triển,
hệ thống sẽ phải thi hành lệnh
-
garbage collection nhằm nỗ lực giải phóng
bộ nhớ cho các phân bổ tương lai.
-
Giờ thì có thể đưa ra rằng các
sự kiện GC sẽ xử lý khác nhau
-
tùy thuộc vào loại thời gian chạy
Android mà bạn đang sử dụng.
-
Ví dụ trong Dalvik, nhiều sự kiện GC
sẽ chặn các sự kiện của toàn hệ thống,
-
nghĩa là bất kỳ mã quản lý nào đang chạy
đều sẽ dừng lại đến khi nó thi hành xong.
-
Điều này sẽ trở thành vấn đề nếu các GC
này mất nhiều thời gian hơn bình thường
-
hoặc cả tấn của chúng đang chạy cùng lúc,
-
vì nó sẽ ăn vào khung thời gian
của bạn một cách đáng kể.
-
>> Và cần biết rằng,
-
các kỹ sư Android đã dành rất nhiều
thời gian đảm bảo các sự kiện này
-
chạy nhanh hết mức có thể nhằm giảm
thiểu gián đoạn, điều này được cho là
-
vẫn có thể gây ra một số vấn đề về
hiệu suất ứng dụng trong mã code của bạn.
-
Thứ nhất, phải hiểu rằng ứng dụng của bạn
càng mất nhiều thời gian với các GC trong
-
một khung nhất định thì nó càng mất ít
thời gian cho phần logic còn lại
-
cần có để giữ bạn trong
hàng rào 16 mili giây.
-
Vì vậy, nếu bạn có rất nhiều GC hoặc một
vài cái rất dài diễn ra kế tiếp,
-
nó có thể khiến thời gian xử lý khung
của bạn vượt qua 16 mili giây.
-
việc dựng hàng rào sẽ gây ra những ràng
buộc hoặc bất lợi cho người dùng của bạn.
-
Thứ hai, cần hiểu dòng mã của bạn
có thể đang hoạt động khiến các GC
-
xảy ra thường xuyên hơn, hoặc khiến chúng
kéo dài lâu hơn thời gian thông thường.
-
Chẳng hạn nếu bạn đang phân bổ một
kho đối tượng tại phần trong cùng của
-
một vòng mã chạy trong một thời gian dài,
sau đó bạn gây ô nhiễm vùng
-
bộ nhớ với rất nhiều đối tượng và bạn
kết thúc việc khởi động rất nhiều GC
-
một cách nhanh chóng, do áp lực
bộ nhớ bổ sung này.
-
Và mặc dù chúng ta đang ở trong
một môi trường bộ nhớ có quản lý,
-
các lỗ hổng bộ nhớ vẫn có thể xảy ra.
-
Mặc dù chúng không dễ dàng được
tạo như những ngôn ngữ khác.
-
Những lỗ hổng này làm ô nhiễm trung tâm
của bạn với các đối tượng không được
-
giải phòng trong một sự kiện, làm giảm
đáng kể không gian mà bạn được sử dụng
-
khiến nhiều sự kiện GC khác khởi động
theo cách thông thường do kết quả của nó.
-
Vì vậy, đó là một thỏa thuận, ý tôi là
-
nếu bạn muốn giảm số lượng các sự kiện GC
xảy ra trong một khung nhất định,
-
bạn cần tập trung vào tối ưu hóa việc
sử dụng bộ nhớ cho các ứng dụng của mình.
-
Từ góc độ mã code, có thể sẽ rất khó
để theo dõi nơi mà các vấn đề
-
tương tự phát sinh, nhưng
-
thật may mắn, Android SDK đã có một bộ
công cụ mạnh mẽ theo ý bạn.
-
Hãy cùng xem nhé.