Using session to do internationalization-induced memory full and repair method of old area

Source: Internet
Author: User

Preface: Yesterday Overtime taxi home, saw a Land Rover in front of the high-speed drive on the giant slow, blocking the way I took the taxi, so with the driver spit trough a sentence: "Front of this car how so face ah?" , the driver was silent for about 3 seconds, said a rich philosophical words: "No face car, only the dough." Borrowing this sentence in software development is: "No face code, only the face of the program ape." Only this time I am the monkey of the program. (Face: Is a dialect, the effect is indecision, slow reaction, no ideas, good bullying and so on).

The background is this, the recent project to do internationalization, mainly based on the spring i18 to do, through the interceptor to intercept the URL of the request contains the locale parameter, if the locale parameter specifies a language type, the information displayed on the page is obtained by the specified type. If the content of this field, if LOCALE=ZH_CN, then content= "Hello", if Locale=en_us, then content= "Hello"; return page, also according to Locale, in the return page before the path to the specific directory, Return to SAYHI.HTML,LOCALE=ZH_CN when return Cn/sayhi.html,locale=en_us when returned us/sayhi.html, this can display different content of welcome page, general internationalization also do this, the same set of code, Internationalization can be done with different configurations.

So the first time my interceptor code was written like this:

 Public classLocalehandleinterceptorextendsLocalechangeinterceptor {@Override Public BooleanPrehandle (HttpServletRequest request, httpservletresponse response, Object handler)throwsservletexception {String Newlocale= Request.getparameter ( This. Getparamname ()); if(Newlocale! =NULL) {Localeresolver localeresolver=Requestcontextutils.getlocaleresolver (Request); if(Localeresolver = =NULL) {                Throw NewIllegalStateException ("No localeresolver found,may is not config localeresolver bean!"); } locale Locale=stringutils.parselocalestring (Newlocale);            Localeresolver.setlocale (Request, response, locale);        Request.getsession (). SetAttribute (Sessionlocaleresolver.locale_session_attribute_name, LOCALE); } Else{Object Localobject=request.getsession (). getattribute (Sessionlocaleresolver.locale_session_attribute_name); if(NULL==localobject) {locale locale=Requestcontextutils.getlocale (Request); Locale= (NULL= = locale)?Locale.getdefault (): Locale;            Request.getsession (). SetAttribute (Sessionlocaleresolver.locale_session_attribute_name, LOCALE); }        }        //Proceed in any case.        return true; } @Override Public voidPosthandle (HttpServletRequest request, httpservletresponse response, Object handler, Modelandview Modelandview)throwsException {if(NULL!=Modelandview) {            //locale locale =//(Locale) request.getsession (). getattribute (sessionlocaleresolver.locale_session_attribute_name);Locale locale =(Locale) webutils.getsessionattribute (request, sessionlocaleresolver.locale_session_attribute_name); Modelandview.setviewname (locale.tostring ()+ "/" +modelandview.getviewname ()); }    }}

After writing, ran a few examples, changed a locale parameter settings are no problem, this thing is done.

after a period of time to go online before the stress test, with LoadRunner 500 users to test Tomcat (JVM xmx=1024m) When the curve is strange, just start to behave normally, but about 30 seconds after TPs dropped sharply, a minute later TPs tends to 0, But Tomcat did not report an oom memory overflow, access a URL with a browser or return, use Gcutil to view the memory recovery situation, found that every second is doing full GC, so with Jmap the current Tomcat stack out, See many Concurrenthashmap objects, the object has a lot of locale objects, Lenovo to this code recently only added to the international interceptor, and then doubted whether the session caused by, at first did not change the code, Instead, find the Web. XML under Tomcat's Conf, adjust the session-timeout for 1 minutes, re-test the problem or reproduce, re-examine the code, discover that this code is causing the problem, comment it off as normal:

Object localobject = Request.getsession (). getattribute (Sessionlocaleresolver.locale_session_attribute_name);

after the problem is found, the request.getsession () is parsed, and this method internally calls the Request.getsession (True), which is created without a session, causes too many session object creation to store the locale after a stress test, and moves to the JVM old area after a certain Mina GC. Causes a frequent full GC, slowing down the entire response. Then why not go to oom? My guess is that the response is slow and slows down the request of the pressure-measuring machine, and the full GC can clean out some space every time, avoiding oom. Don't know if this is it? The way that this session is based on itself can be internationalized, but I call the wrong way, so refer to spring's localechangeinterceptor and The source code of the Sessionlocaleresolver class modifies our interceptor codes as follows:

 Public classLocalehandleinterceptorextendsLocalechangeinterceptor {@Override Public BooleanPrehandle (httpservletrequest request, httpservletresponse response, Object handler)throwsservletexception {String localname= Request.getparameter ( This. Getparamname ()); Localeresolver Localeresolver=Requestcontextutils.getlocaleresolver (Request); if(Localeresolver = =NULL) {            Throw NewIllegalStateException ("No localeresolver Found:not in a dispatcherservlet request?")); } locale Locale=Localeresolver.resolvelocale (Request); if(! (NULL==localname | |locale.tostring (). Equalsignorecase (LocalName))) {Localeresolver.setlocale (Request, response, (NULL= = LocalName?Locale.getdefault (): stringutils.parselocalestring (LocalName)); }        //Proceed in any case.        return true; } @Override Public voidPosthandle (HttpServletRequest request, httpservletresponse response, Object handler, Modelandview Modelandview)throwsException {//locale locale = (locale) request.getsession (). getattribute (Sessionlocaleresolver.locale_session_attribute_name );        if(NULL!=Modelandview) {            //Filter The JSON back caseLocale locale =requestcontextutils.getlocaleresolver (Request) Resolvelocale (request); Modelandview.setviewname (locale.tostring ()+"/"+modelandview.getviewname ()); }    }}

After that, there's no problem with the pressure test.

PostScript: The code does not pass the pressure test is not enough to talk about excellent, out of any problems, before the pre-entrenched concept, from the source analysis, bold guess, careful verification, and keep the learning mentality, bypassing the problem is easy, but face the problem requires courage and patience, stepping over it, you will be a further before the meeting, And the technological advance is the real wealth of the technician.

Using session to do internationalization-induced memory full and repair method of old area

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.