2014年5月14日星期三

ThreadLocal causing memory leaks ?

code is as follows :
public class DateUtil {
private static ThreadLocal sdf = new ThreadLocal () {
protected DateFormat initialValue () {
return new SimpleDateFormat ("yyyy-MM-dd");
};
};


public static DateFormat getDateFormat (ThreadLocal tl) {
return tl.get ();
}
public static String format (Date date) {
if (date == null) {
return "";
} .
return getDateFormat (sdf) format (date);
}



public static Date parse (String st) throws ParseException {
return getDateFormat (sdf) parse (st).;
}
}

recently doing a Web project , because SimpleDateFormat is not thread- safe, so think of using ThreadLocal to encapsulate a moment , the project uses a thread pool , colleagues say such written words will cause instance of an object can not be recycled , leading to memory leaks, (ps: my colleagues said ThreadLocal thread-safe is not to solve the problem ) want to look at the big cattle , so in the end be able to use the line , if it will lead to memory leaks, I beg you analyze it.
------ Solution ---------------------------------------- ----
first, you write will not cause a memory leak or a problem instance of an object can not be recycled .
your colleague said , ThreadLocal is not to solve the problem of thread safety is also wrong to say , ThreadLocal is another idea , I think you should also know that I will not elaborate . When I say
memory leaks , and I do not see any problem, as worry about your colleagues, I think he probably felt every ThreadLocal sdf are placed in different Thread , if Thread not to be destroyed has been present in the memory of it, it still needs to look at the project and see a thread-safe and memory , there is no need for such strict on both sides , which side can regress it.
------ Solution ---------------------------------------- ----
personally think that as long as the life cycle of your thread is not long , absolutely no problem , JDK7 of ThreadLocalRandom is a similar approach.

If you feel insecure , you can add a remove method , finally ending in the block method execution ThreadLocal.remove


or your colleagues say is right , ThreadLocal more thread context is used to store information related
------ Solution ------------- -------------------------------
exhausted themselves release it.
------ Solution ---------------------------------------- ----
DateFormat is merely a tool , why should the thread isolate it?
------ Solution ---------------------------------------- ----
be synchronized static method , the direct use of DateFormat, simple and brutal and effective.

your colleagues worry , may be afraid of the page when a large amount of concurrent requests , each request must be assigned a ThreadLocal, will take up a lot of memory. As for recycling, feel ThreadLocal an end of the thread , and it will be over.
------ Solution ---------------------------------------- ----
colleagues say that this write words will cause instance of an object can not be recycled , resulting in a memory leak

Why do you ask your colleague next . Why not say that there is no basis for his conclusions .

As for you, I do not see what's the problem
------ Solution ------------------------- -------------------
Why are so easy to use memory leak it? java general code at best memory overflow. . . .
------ Solution ---------------------------------------- ----
looked under the landlord 's title , this deal is feasible. There are a few suggestions:
1, DateFormat insecurity occurs when multiple threads call the same result DateFormat instance , while we are all written in the general string parsing tools in the tool class methods , new SimpleDateFormat parse this there is no question of the thread , if the landlord does not involve particularly large web projects date parsing operation , no need to do too much handling .
2, the landlord using ThreadLocal encapsulation , so that each thread will contain a Dateformat instance , this can indeed solve the thread-safety issues , after all, between Dateformat separate thread , but the landlord a little note , ThreadLocal declarations follow the current cycle threads, also said the landlord with a thread pool , so used to put back into the thread pool thread , which is after every user access , Threadlocal did not release the memory leak does count , remember exhausted remove ( you can the return filter chain carried remove, ps: there is no other better place , if you run the code on the remove, it is not as efficient method 1 ) .
3, ThreadLocal to save data in the context of the main thread , the thread safety as for solving the problem , seemingly does not matter much , but the clever use can be resolved, the landlord 's example also illustrates this point .
------ Solution ---------------------------------------- ----
personally feel that this class should not exist ThreadLocal best not to use SimpleDateFormat not thread safe if you want to use this to parse then every times on the new accounting did nothing so much space if you just want to format it can use commons of FastDateFormat thread safety
------ For reference only ---------------------------------------
but also that thing seems csdn when I did not ask .
------ For reference only -------------------------------------- -

ask questions if you do not manually release the memory leak it appears , read a lot of information on the Internet and some say there may be some said it would not exist , really confused ?
------ For reference only -------------------------------------- -

Well, he said the usage is correct, but this seems to be using it, after all, is a solution Well ,
------ For reference only ---- -----------------------------------

Well , I feel that using a thread pool , that thread back into the thread pool runs out after other requests continue to be used , the corresponding object instance Sdf it has always existed in this thread ThreadLocalMap inside, so what does not seem to have a memory leak problem.
------ For reference only -------------------------------------- -

but this tool is not thread -safe, multithreaded simultaneous access to an instance problematic .
------ For reference only -------------------------------------- -

This fall is also a good solution.
------ For reference only -------------------------------------- -

since even the moderators are saying , it seems that it is feasible to write , then do not worry about it , or so use it ,
------ For reference only --- ------------------------------------
then hang the day tomorrow to tie knot points .
------ For reference only -------------------------------------- -

but this tool is not thread -safe, multithreaded simultaneous access to an instance problematic .  
Oh , SimpleDateFormat class

public Date parse(String text, ParsePosition pos)
{
        calendar.clear(); // Clears all the time fields

        ......//对calendar的一些操作

        else parsedDate = calendar.getTime();
}

thread safety hazard reason is the calendar thread shared.
brutally simple solution is to use the code synchronized SimpleDateFormat
There is ThreadLocal, let SimpleDateFormat threads localization ( each thread has its own copy of SimpleDateFormat, course calendar will not be shared between threads of the ) .

But I have a question :
landlord did not know specifically how to use your DateUtil of this class . This class does not inherit seemingly Thread or achieve Runnable.
So when you use DateUtil getDateFormat , seemingly out every time a new SimpleDateFormat, did not use the features ThreadLocal ah.

private static ThreadLocal sdf = new ThreadLocal () {
protected DateFormat initialValue () {
return new SimpleDateFormat ("yyyy-MM-dd");
};
};
above , your code should be written in a thread class in it, instead of writing instruments in this category


------ For reference only ---------------------------------- -----

but this tool is not thread -safe, multithreaded simultaneous access to an instance problematic .          
Oh , SimpleDateFormat class   
  

public Date parse(String text, ParsePosition pos)
{
        calendar.clear(); // Clears all the time fields

        ......//对calendar的一些操作

        else parsedDate = calendar.getTime();
}
  
thread safety hazard reason is the calendar thread shared.   
brutally simple solution is to use the code synchronized SimpleDateFormat   
There is ThreadLocal, let SimpleDateFormat threads localization ( each thread has its own copy of SimpleDateFormat, course calendar will not be shared between threads of the ) .   
  
But I have a question :   
landlord did not know specifically how to use your DateUtil of this class . This class does not inherit seemingly Thread or achieve Runnable.   
So when you use DateUtil getDateFormat , seemingly out every time a new SimpleDateFormat, did not use the features ThreadLocal ah.   
  
private static ThreadLocal sdf = new ThreadLocal () {   
protected DateFormat initialValue () {   
return new SimpleDateFormat ("yyyy-MM-dd");   
};   
};   
above , your code should be written in a thread class in it, instead of writing instruments in this category   
  
 
This is a utility class Well , if a request corresponds to a thread a, when I called DateUtil the format methods or parse method in which this request, if this thread is When first visit In this way, the thread will be stored in a corresponding member variable ThreadLocalMap a key for the above class member variables and values ​​of a new ThreadLocal SimpleDateFormat created after the end of this emphasis , the request corresponding to the thread pool thread will be recycled inside . For the other emphasizes the use , if that other person is also launching a page emphasizes , also assigned to this thread just a, then it will go directly to a member variable ThreadLocalMap it to ThreadLocal object has been stored for the key to get into the SimpleDateFormat.
In other words corresponding to each thread in the thread pool inside , will create a SImpleDateFormat object only when the first call DateUtil way inside , and store it in a thread inside ThreadLocalMap , and later it was stress when assigned to take on that thread directly from ThreadLocalMap inside, avoiding the overhead of each call are new , this will be between singleton with prototype , my personal understanding is such inadequacies look large cattle a lot of guidance .
------ For reference only -------------------------------------- -
meaning of the landlord is to give each thread by injecting a ThreadLocal sdf DateUtil tools do ?
------ For reference only -------------------------------------- -



not give each thread inject a sdf, but to each thread creates a SimpleDateFormat instance , the member variables are stored inside in Thread
ThreadLocalMap the value of , map the key to sdf.
------ For reference only ----------------------- ----------------

your second point , I do not quite understand , ThreadLocal is not released , but only this one instance ThreadLocal object memory, all the threads are not sharing what this ThreadLocal instance , only the corresponding SimpleDateFormat with different threads and different, so do not feel the release did not affect it ?
------ For reference only -------------------------------------- -

your second point , I do not quite understand , ThreadLocal is not released , but only this one ThreadLocal object instance in memory, all the threads are not sharing what this ThreadLocal instance , with just the corresponding SimpleDateFormat different threads and different, so do not feel the release did not affect it ?   ah indeed no impact , but your colleague is not to say what a memory leak , so I said above, is considered a memory leak , after all, you do not run out of the release .
------ For reference only -------------------------------------- -
Thank you for the advice , the problem has been solved, ready to stick to the end of it.

没有评论:

发表评论