Toggle Theme Editor
Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Charcoal

Giải Phóng Bộ Nhớ Trong Java

Discussion in 'Xây dựng ứng dụng desktop standalone' started by kienxx, 22/7/18.

  1. kienxx

    kienxx Member

    Mình có hàm refresh dữ liệu, mỗi lần chạy hàm thì để ý dung lượng bộ nhớ (theo dõi trên Task Manager) cứ liên tục đẩy lên và ko giảm khi đã chạy xong. Nên mình đã test thử như sau.
    VD bây giờ main chạy 2 hàm: Hàm 1 rồi tới hàm 2.
    - Hàm 1 đẩy dung lượng (theo dõi trên Task Manager) lên khoảng 100k.
    - Hàm 2 đơn giản là 1 vòng lặp while (true) ko làm gì cả, nếu chỉ chạy duy nhất hàm này mất khoảng vài k.
    Theo dõi trên Task Manager thì mình thấy dung lượng luôn giữ ở mức 100k ko giảm, mặc dù đã chạy sang hàm thứ 2.
    Câu hỏi của mình là tại sao lại như vậy ai giải thích được không, vì mình nghĩ là các biến cục bộ, lệnh cục bộ trong hàm 1 sau khi chạy xong đã được giải phóng rồi. Tiếp theo là cách để chạy sang hàm 2 nó sẽ giải phóng bộ nhớ hết các hàm trước đó đã chạy xong. Xin cảm ơn.
     
  2. JackV

    JackV Administrator Staff Member

    Last edited: 24/7/18
    kienxx likes this.
  3. kienxx

    kienxx Member

    Thông tin trên đã giúp mình hiểu vì sao
    Mình để khoảng 3 tiếng thì nó có giảm xuống tiệm cận lúc khởi động và tại sao mình dùng System.gc() thì ko có tác dụng
    Mình nghĩ thế này ko biết có đúng ko, là những hàm chạy lặp thường xuyên thì nên dùng biến class, còn ít chạy thì dùng biến cục bộ theo hàm.. Suy nghĩ như vậy có chính xác ko?
     
    D.A.N_3002 likes this.
  4. JackV

    JackV Administrator Staff Member

    suggests thôi chứ k phải lệnh thực hiện ngay đâu.

    Không phải biến cục bộ hay toàn cục đâu, mà là nên sử dụng loại dữ liệu kiểu nào, bạn thử 2 trường hợp này
    String s = "abc";
    StringBuilder sb = new StringBuilder("abc/");
    đưa s hoặc sb vào vòng lặp gán những String khác nhau xem bộ nhớ thay đổi thế nào nhé.
     
  5. kienxx

    kienxx Member

    Mình đã test System.out.println và khá nhiều kiểu thì mình nhận thấy là dùng biến cục bộ có trường hợp mất bộ nhớ = biến static, có trường hợp mất nhiều hơn.
    Còn test theo bạn nói thì dùng String tốn ít hơn StringBuilder.
    Nói chung mình vẫn ko biết cách giải quyết vấn đề nó đẩy bộ nhớ lên quá cao so với những gì nó thực hiện ~X(
     
  6. JackV

    JackV Administrator Staff Member

    Cái đó thì bạn cho xem code test với.
    hả, thực tế thì bắn nhau chỉ có bóp cò súng và đạn bay thôi hay còn rất nhiều thứ nữa bạn? Người đâu, đạn đâu, súng đâu, ...
    Vấn đề dọn rác là do JVM tự động thực hiện khi nó cảm thấy cần thiết, bạn xem tài liệu bộ nhớ heap của JVM nhé.
     
    D.A.N_3002 likes this.
  7. kienxx

    kienxx Member

    @JackV: Hôm qua mà xóa mất rồi, chỉ là khai báo rồi cho vô vòng lặp println ra thôi
     
  8. Joe

    Joe Thành viên VIP

    You confuse JAVA Virtual Machine with an ordinary app. JVM always starts with a default heap/stack (which could be respecified by the switches: -Xms/-Xmx and -Xss). What you see on Task manager Screen (TMS) is the default memory claimed by JVM. Therefore your tiny java loops or java apps won't explicitly appear on TMS, but inside the memory claimed by JVM. Even you run n different JAVA apps and you see n JAVA entries on TMS but they all share the same JVM and the TMS shows no significant increase or decrease (it's administered by Operating System and JVM does the GC itself. It rarely needs to acquire extra memory. The way you asked tells me that you don't have enough foundation on Computer Science and JVM. Hence it's difficult to tell you more about the details)

    You err tremendously. String (object or primitive) is a FINAL object. Meaning unchangeable or immutable. Any manipulation of String will create a NEW string with the copy of the old string content + changes. The original string is discarded and becomes Garbage. The more a string is manipulated the more garbage emerges. Meaning: more memory because of more garbage.
    On the other hand, StringBuilder is purposed for reduction of garbage. Meaning: using StringBuilder (or StringBuffer) reduces the emerging garbage. Also less memory because of less garbage. And you contradict JAVA with your statement "Còn test theo bạn nói thì dùng String tốn ít hơn StringBuilder."
     
    Last edited: 31/7/18
  9. hoithegiantinhlagi

    hoithegiantinhlagi Active Member

    @kienxx anything @Joe has said is absolutely right, you should learn more about computer science and especially in memory management.
    About you test, I wanna share you a tiny story. In Java performance of these types are StringBuilder > StringBuffer > String.
    In fact when you create a variable: String str = "abc", the true story behind the scene was String abc = new StringBuilder("abc"), It's a waste of memory if you user String instead of StringBuilder.
    What about StringBuffer? StringBuffer "likes" StringBuilder, both have good performance than String, but StringBuilder is still faster than StringBuffer slightly, why???
    Just because StringBuffer is synchronous, on the other hand StringBuilder is asynchronous! and of course nothing is free, StringBuilder isn't thread safe so be careful when you wanna use this type.
     
    kienxx and Joe like this.

Chia sẻ trang này

Loading...