2013-04-17 28 views
11

Đây có thể là một câu hỏi ngu ngốc (hoặc chỉ làm cho tôi trông ngu ngốc :)), tuy nhiên tôi sẽ quan tâm đến cách làm việc với các đối tượng String dài trong bối cảnh các đối tượng ngắn ngủi.Các chuỗi tĩnh dài trong các đối tượng sống ngắn

Suy nghĩ về các truy vấn SQL dài trong công việc cron hoặc các lớp ẩn danh, lệnh hoặc chức năng. Đây là những lớp học rất ngắn và thậm chí sẽ sử dụng các chuỗi dài này một lần trong suốt cuộc đời của chúng trong hầu hết thời gian. Điều gì là tốt hơn? Để xây dựng một chuỗi nội tuyến và để cho nó được thu thập với cá thể, hoặc làm cho nó tĩnh cuối cùng anyway và để cho họ ngồi trong bộ nhớ vô ích cho đến khi các lớp học tiếp theo instantiation?

+0

là các truy vấn khác nhau cho mỗi người trong số các đối tượng trong thời gian ngắn? –

+0

Tùy thuộc vào mức độ thường xuyên của các lớp học ngắn ngủi này được tạo và nếu các truy vấn giống nhau trong toàn bộ –

+0

Không, tất cả đều giống nhau cho mọi trường hợp – user1405469

Trả lời

8

Vâng, chỉ có quá nhiều quyền kiểm soát mà bạn có thể có đối với những gì xảy ra với Chuỗi. Thậm chí nếu bạn tạo nội tuyến, chuỗi đó có thể sẽ được thêm vào nhóm hằng số chuỗi của JVM và sẽ được tái sử dụng khi bạn khai báo lại, vì vậy trong thực tế, bạn có thể sẽ sử dụng lại cùng một Chuỗi đối tượng theo một trong hai cách.

Trừ khi chuỗi quá lớn đến nỗi nó có tác động đến hiệu suất của ứng dụng của bạn, tôi sẽ không lo lắng về nó và chọn tùy chọn có vẻ dễ đọc hơn đối với tôi.

Nếu chuỗi đó sẽ chỉ được sử dụng ở một điểm cụ thể của mã, bên trong một phương pháp, tôi sẽ khai báo nội tuyến, tôi muốn có các biến trong phạm vi nhỏ nhất có thể, nhưng ý kiến ​​ở đây có thể thay đổi. Nếu không có thay đổi gì, và nó có vẻ hợp lý trong trường hợp sử dụng cụ thể của bạn, bằng mọi cách khai báo chuỗi là tĩnh, một lần nữa, tôi nghi ngờ nó sẽ ảnh hưởng đến hiệu suất.

2

Hằng số chuỗi đi vào nhóm không đổi của một lớp và không thể được tối ưu hóa, tức là được xử lý đủ tốt.

Tạo chuỗi dài không làm tĩnh. Để sử dụng SQL báo cáo đã chuẩn bị với một người giữ chỗ ?. Các lưu giữ tương tự cho các chuỗi có phần giữ chỗ: sử dụng MessageFormat.

Để rõ ràng. Sau đây không mất thêm bất kỳ chi phí nào:

static final String s = "... long string ..."; 
+0

Tôi thực sự thích phần đầu tiên và cuối cùng của nhận xét của bạn . Ý tưởng chuẩn bị và các ý tưởng định dạng tin nhắn của bạn không áp dụng trong trường hợp của tôi vì các đối tượng/cronjobs này thực sự chỉ thực thi một bản cập nhật sql đơn, nhưng dài và được thực hiện với nó. Không có thông số nào. Tuy nhiên, mặc dù bạn sử dụng các câu lệnh và chuỗi đã chuẩn bị sẵn sàng với trình giữ chỗ, bạn vẫn phải lưu trữ những chuỗi dài đó bằng cách nào đó :). – user1405469

-2

Khi bộ nhớ còn lại bị giới hạn, JVM thường sẽ làm sạch không gian và không sử dụng các lớp không được sử dụng. Vì vậy, có chuỗi dài như biến tĩnh sẽ không làm hại nhiều trong quan điểm của tôi

+1

-1.Không được xếp dỡ như thế. – Lokesh

+0

Bạn có thể đọc thêm về xóa bộ nhớ tại blog này http://www.javaworld.com/jw-06-1998/jw-06-techniques.html – AurA

+0

@loki bạn đã sử dụng tùy chọn JVM 'CMSClassUnloadingEnabled' hoặc xem sử dụng bộ nhớ hay chưa thông qua JConsole vv của một ứng dụng? –

-2

Nếu bạn cảm thấy các chuỗi của bạn có thể chiếm nhiều bộ nhớ thì không làm cho chúng tĩnh hoặc khai báo chúng bằng String literal. Vì cả hai sẽ được lưu trữ trong không gian permgen và hầu như sẽ được thu gom rác thải [có cơ hội nhưng mỏng, statics có thể không bao giờ được thu gom rác là bạn chưa tạo trình nạp lớp của riêng mình]. Vì vậy, tạo ra chuỗi sử dụng nhà điều hành mới do đó sẽ được tạo ra trong đống và có thể dễ dàng thu gom rác tức là

String str = new String("long string"); 

EDIT:

Làm thế nào chuỗi được lưu trữ: http://www.ntu.edu.sg/home/ehchua/programming/java/J3d_String.html

EDIT:

Đã có một cuộc thảo luận dài dưới đây về cách Chuỗi mới hoạt động. Đối số được trình bày là String mới sẽ tạo 2 đối tượng một trong đống và một đối tượng trong nhóm. Điều này là sai, nó không đúng theo mặc định và bạn có thể buộc java để làm điều đó bằng cách gọi phương thức thực tập.Để sao lưu lý luận của tôi sau đây là javadoc từ lớp Strin cho phương pháp thực tập:

tập

public String thực tập() trả về một đại diện kinh điển cho đối tượng chuỗi. Một nhóm các chuỗi, ban đầu trống rỗng, được duy trì riêng bởi chuỗi lớp.

Khi phương thức thực thi được gọi, nếu nhóm đã chứa một chuỗi bằng đối tượng String này được xác định bằng phương thức equals (Object) , thì chuỗi từ hồ bơi được trả về. Nếu không, đối tượng String này được thêm vào hồ bơi và tham chiếu đến đối tượng Chuỗi này sẽ được trả lại.

Sau đó cho bất kỳ hai chuỗi s và t, s.intern() == t.intern() là đúng nếu và chỉ khi s.equals (t) là đúng.

Tất cả các chuỗi ký tự và các biểu thức hằng số có giá trị chuỗi là được thực hiện. Các chuỗi ký tự được định nghĩa trong §3.10.5 của Ngôn ngữ Java Đặc điểm kỹ thuật

Như có thể thấy ở trên rằng nếu String mới luôn tạo ra một đối tượng trong hồ bơi thì phương thức thực tập sẽ hoàn toàn vô ích !! Ngoài ra một cách hợp lý nó không có ý nghĩa gì cả.

EDIT:

Cũng đọc câu trả lời cho bài đăng này: String pool creating two string objects for same String in Java

+0

Trong trường hợp này, có thể có thể thu gom rác, nhưng "chuỗi dài" được lưu trong permgen phải không? – mjaggard

+0

Vì vậy, u có nghĩa là để nói tất cả các chuỗi đi permgen cho dù bạn tạo chữ hoặc sử dụng mới? Whats sử dụng phương thức intern() sau đó? Những gì bạn thực sự cần phải tạo String bằng cách sử dụng mới? – Lokesh

+0

@mjaggard: Vui lòng biện minh cho lý lẽ của bạn hoặc loại bỏ downvote – Lokesh

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