Sự khác biệt giữa những người khác trên heap và


Câu trả lời:


169

Kho lưu trữ trên heap đề cập đến các đối tượng sẽ có mặt trong vùng heap Java (và cũng chịu sự điều chỉnh của GC). Mặt khác, cửa hàng heap off đề cập đến các đối tượng (tuần tự hóa) được quản lý bởi EHCache, nhưng được lưu trữ bên ngoài heap (và cũng không chịu sự điều chỉnh của GC). Khi cửa hàng heap tiếp tục được quản lý trong bộ nhớ, nó chậm hơn một chút so với cửa hàng trên heap, nhưng vẫn nhanh hơn so với cửa hàng đĩa.

Các chi tiết nội bộ liên quan đến việc quản lý và sử dụng cửa hàng heap không rõ ràng trong liên kết được đăng trong câu hỏi, vì vậy sẽ rất khôn ngoan khi kiểm tra các chi tiết của Terracotta BigMemory , được sử dụng để quản lý đĩa ngoài cửa hàng. BigMemory (cửa hàng ngoài heap) sẽ được sử dụng để tránh chi phí hoạt động của GC trên một heap lớn vài Megabyte hoặc Gigabyte. BigMemory sử dụng không gian địa chỉ bộ nhớ của quy trình JVM, thông qua ByteBuffers trực tiếp không chịu sự điều chỉnh của GC không giống như các đối tượng Java gốc khác.


18
+1 để đề cập đến ByteBuffers trực tiếp để khám phá thêm;)
Max

3
ByteBuffers trực tiếp cung cấp quyền truy cập vào bộ nhớ không được quản lý, nhưng bản thân chúng phải tuân theo GC (trái ngược với dữ liệu mà chúng trỏ đến). Điều này rất quan trọng vì một ByteBuffer trực tiếp (loại ByteBuffer.allocateDirect, không phải loại MMap) sẽ được thu thập bởi GC và khi được thu thập, Deallocater cũng sẽ được kích hoạt, thu thập bộ nhớ không được quản lý một cách hiệu quả.
Nitsan Wakart 23/2/2015

Sử dụng Không an toàn để phân bổ các đối tượng có vẻ như có hiệu suất đọc và ghi tốt hơn đáng kể so với Onheap / DirectByteBuffers / ByteBuffers. ashkrit.blogspot.com/2013/07/ trên
Joe C

98

từ http://code.google.com.vn/p/fast-serialization/wiki/QuickStartHeap Offer

Heap-Offloading là gì?

Thông thường tất cả các đối tượng không tạm thời mà bạn phân bổ được quản lý bởi trình thu gom rác của java. Mặc dù VM thực hiện tốt công việc thu gom rác, nhưng tại một thời điểm nhất định, VM phải thực hiện cái gọi là 'Full GC'. Một GC đầy đủ liên quan đến việc quét Heap được phân bổ hoàn chỉnh, điều đó có nghĩa là các lần tạm dừng / chậm lại của GC tỷ lệ thuận với kích thước của heap ứng dụng. Vì vậy, đừng tin bất cứ ai nói với bạn 'Bộ nhớ là rẻ'. Trong tiêu thụ bộ nhớ java làm tổn thương hiệu suất. Ngoài ra, bạn có thể nhận được các tạm dừng đáng chú ý bằng cách sử dụng kích thước heap> 1 Gb. Điều này có thể khó chịu nếu bạn có bất kỳ nội dung gần thời gian thực nào đang diễn ra, trong một cụm hoặc lưới, một quy trình java có thể không phản hồi và bị loại khỏi cụm.

Tuy nhiên, các ứng dụng máy chủ ngày nay (thường được xây dựng dựa trên các khung bloaty ;-)) dễ dàng yêu cầu hàng đống vượt xa 4Gb.

Một giải pháp cho các yêu cầu bộ nhớ này là 'giảm tải' các phần của các đối tượng cho heap không java (được phân bổ trực tiếp từ HĐH). May mắn thay, java.nio cung cấp các lớp để phân bổ trực tiếp / đọc và ghi các phần bộ nhớ 'không được quản lý' (ngay cả các tệp ánh xạ bộ nhớ).

Vì vậy, người ta có thể phân bổ số lượng lớn bộ nhớ 'không được quản lý' và sử dụng điều này để lưu các đối tượng ở đó. Để lưu các đối tượng tùy ý vào bộ nhớ không được quản lý, giải pháp khả thi nhất là sử dụng Nối tiếp. Điều này có nghĩa là ứng dụng tuần tự hóa các đối tượng vào bộ nhớ ngoài, sau này đối tượng có thể được đọc bằng cách sử dụng giải tuần tự hóa.

Kích thước heap được quản lý bởi java VM có thể được giữ ở mức nhỏ, do đó, tạm dừng GC là trong millis, mọi người đều vui vẻ, hoàn thành công việc.

Rõ ràng là hiệu năng của bộ đệm heap như vậy phụ thuộc chủ yếu vào hiệu suất của việc thực hiện tuần tự hóa. Tin tốt: vì một số lý do FST-serialization khá nhanh :-).

Các kịch bản sử dụng mẫu:

  • Bộ nhớ cache phiên trong một ứng dụng máy chủ. Sử dụng tệp ánh xạ bộ nhớ để lưu trữ gigabyte phiên người dùng (không hoạt động). Khi người dùng đăng nhập vào ứng dụng của bạn, bạn có thể nhanh chóng truy cập dữ liệu liên quan đến người dùng mà không phải xử lý cơ sở dữ liệu.
  • Bộ nhớ đệm của các kết quả tính toán (truy vấn, trang html, ..) (chỉ áp dụng nếu tính toán chậm hơn so với giải tuần tự hóa đối tượng kết quả).
  • kiên trì rất đơn giản và nhanh chóng bằng cách sử dụng các tập tin ánh xạ bộ nhớ

Chỉnh sửa: Đối với một số trường hợp, người ta có thể chọn các thuật toán Bộ sưu tập Rác phức tạp hơn, chẳng hạn như ConcurrencyMarkAndSweep hoặc G1 để hỗ trợ các đống lớn hơn (nhưng điều này cũng có giới hạn vượt quá 16 GB). Ngoài ra còn có một JVM thương mại với cải tiến 'không ngừng' (Azul) được cải tiến.


4
"phân bổ số lượng lớn bộ nhớ 'không được quản lý' và sử dụng điều này để lưu các đối tượng ở đó" - bạn không thể lưu đối tượng ngoài luồng. Bạn có thể lưu trữ nguyên thủy, bạn có thể gói chúng trong bất kỳ thư viện nào bạn thích, nhưng đây không phải là Đối tượng. Dữ liệu bạn đặt offheap không có tiêu đề đối tượng, bạn không thể đồng bộ hóa trên đó, bạn không thể tham chiếu nó với trường tham chiếu trong một số đối tượng khác.
Nitsan Wakart 23/2/2015

41

Heap là nơi trong bộ nhớ nơi các đối tượng được phân bổ động của bạn sống. Nếu bạn đã sử dụng newthì đó là trên đống. Điều đó trái ngược với không gian ngăn xếp, đó là nơi ngăn xếp chức năng sống. Nếu bạn có một biến cục bộ thì tham chiếu đó nằm trên ngăn xếp. Heap của Java là đối tượng thu gom rác và các đối tượng có thể sử dụng trực tiếp.

Bộ lưu trữ heap của EHCache đưa đối tượng thông thường của bạn ra khỏi heap, tuần tự hóa nó và lưu trữ dưới dạng byte trong một đoạn bộ nhớ mà EHCache quản lý. Nó giống như lưu trữ nó vào đĩa nhưng nó vẫn còn trong RAM. Các đối tượng không thể sử dụng trực tiếp trong trạng thái này, chúng phải được khử lưu huỳnh trước. Cũng không phải thu gom rác.


Nó không chỉ đơn giản là vẫn còn trong đống mà là một hình thức nối tiếp?
Pacerier

1
Làm thế nào mà làm cho nó hiệu quả hơn?
Pacerier

2
Có rất nhiều cách. Vì các đối tượng không còn trên đống Java chính, chúng không lãng phí thời gian của người thu gom rác, chúng không phân mảnh đống JVM và chúng giải phóng không gian cho các đối tượng được sử dụng nhiều hơn. Ngoài ra, vì chúng được tuần tự hóa và có thể không cần thiết trong tương lai trước mắt, chúng có thể được nén, di chuyển khi cần hoặc thậm chí phân trang ra đĩa.
Adam

1
Trong Hotspot, thời gian tạm dừng GC phụ thuộc trực tiếp vào kích thước heap. BigMemory cung cấp sự đánh đổi này bằng cách sử dụng RAM thay vì heap, để giữ cho tạm dừng GC ở mức tối thiểu và tránh chi phí IO của việc truy cập đĩa.
Chander Shivdasani


1

JVM không biết gì về bộ nhớ heap. Ehcache thực hiện bộ đệm trên đĩa cũng như bộ đệm trong bộ nhớ.


1

Không phải 100%; tuy nhiên, có vẻ như heap là một đối tượng hoặc tập hợp không gian được phân bổ (trên RAM) được tích hợp vào chức năng của mã hoặc chính Java hoặc nhiều khả năng là từ chính ehcache và Ram heap có hệ thống riêng như tốt; tuy nhiên, có vẻ như điều này chậm hơn một độ vì nó không được tổ chức, có nghĩa là nó có thể không sử dụng một đống (có nghĩa là một bộ không gian ram dài), và thay vào đó sử dụng các không gian địa chỉ khác nhau có thể làm cho nó kém hiệu quả hơn một chút.

Sau đó, tất nhiên tầng thấp hơn tiếp theo là không gian ổ cứng.

Tôi không sử dụng ehcache, vì vậy bạn có thể không muốn tin tôi, nhưng đó là những gì tôi thu thập được từ tài liệu của họ.

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.