Search Results

Search found 24 results on 1 pages for 'clog'.

Page 1/1 | 1 

  • Redirect C++ std::clog to syslog on Unix

    - by kriss
    I work on Unix on a C++ program that send messages to syslog. The current code uses the syslog system call that works like printf. Now I would prefer to use a stream for that purpose instead, typically the built-in std::clog. But clog merely redirect output to stderr, not to syslog and that is useless for me as I also use stderr and stdout for other purposes. I've seen in another answer that it's quite easy to redirect it to a file using rdbuf() but I see no way to apply that method to call syslog as openlog does not return a file handler I could use to tie a stream on it. Is there another method to do that ? (looks pretty basic for unix programming) ? Edit: I'm looking for a solution that does not use external library. What @Chris is proposing could be a good start but is still a bit vague to become the accepted answer. Edit: using Boost.IOStreams is OK as my project already use Boost anyway. Linking with external library is possible but is also a concern as it's GPL code. Dependencies are also a burden as they may conflict with other components, not be available on my Linux distribution, introduce third-party bugs, etc. If this is the only solution I may consider completely avoiding streams... (a pity).

    Read the article

  • The question regarding cerr cout and clog

    - by skydoor
    Can anybody explain the difference between cerr cout and clog and why does different objects are proposed? I know the differences are as below: 1) cout can redirected but cerr can't 2) clog can use buffer. I am confused about the point 2, I am grateful if anybody can elaborate it more.

    Read the article

  • R ggplot2: Arrange facet_grid by non-facet column (and labels using non-facet column)

    - by tommy-o-dell
    I have a couple of questions regarding facetting in ggplot2... Let's say I have a query that returns data that looks like this: (note that it's ordered by Rank asc, Alarm asc and two Alarms have a Rank of 3 because their Totals = 1798 for Week 4, and Rank is set according to Total for Week 4) Rank Week Alarm Total 1 1 BELTWEIGHER HIGH HIGH 1000 1 2 BELTWEIGHER HIGH HIGH 1050 1 3 BELTWEIGHER HIGH HIGH 900 1 4 BELTWEIGHER HIGH HIGH 1800 2 1 MICROWAVE LHS 200 2 2 MICROWAVE LHS 1200 2 3 MICROWAVE LHS 400 2 4 MICROWAVE LHS 1799 3 1 HI PRESS FILTER 2 CLOG SW 1250 3 2 HI PRESS FILTER 2 CLOG SW 1640 3 3 HI PRESS FILTER 2 CLOG SW 1000 3 4 HI PRESS FILTER 2 CLOG SW 1798 3 1 LOW PRESS FILTER 2 CLOG SW 800 3 2 LOW PRESS FILTER 2 CLOG SW 1200 3 3 LOW PRESS FILTER 2 CLOG SW 800 3 4 LOW PRESS FILTER 2 CLOG SW 1798 (duplication code below) Rank = c(rep(1,4),rep(2,4),rep(3,8)) Week = c(rep(1:4,4)) Total = c( 1000,1050,900,1800, 200,1200,400,1799, 1250,1640,1000,1798, 800,1200,800,1798) Alarm = c(rep("BELTWEIGHER HIGH HIGH",4), rep("MICROWAVE LHS",4), rep("HI PRESS FILTER 2 CLOG SW",4), rep("LOW PRESS FILTER 2 CLOG SW",4)) spark <- data.frame(Rank, Week, Alarm, Total) Now when I do this... s <- ggplot(spark, aes(Week, Total)) + opts( panel.background = theme_rect(size = 1, colour = "lightgray"), panel.grid.major = theme_blank(), panel.grid.minor = theme_blank(), axis.line = theme_blank(), axis.text.x = theme_blank(), axis.text.y = theme_blank(), axis.title.x = theme_blank(), axis.title.y = theme_blank(), axis.ticks = theme_blank(), strip.background = theme_blank(), strip.text.y = theme_text(size = 7, colour = "red", angle = 0) ) s + facet_grid(Alarm ~ .) + geom_line() I get this.... Notice that it's facetted according to Alarm and that the facets are arranged alphabetically. Two Questions: How can I can I keep it facetted by alarm but displayed in the correct order? (Rank asc, Alarm asc). Also, how can I keep it facetted by alarm but show labels from Rank instead of Alarm? Note that I can't just facet on Rank because ggplot2 would see only 3 facets to plot where there are really 4 different alarms. Thanks kindly for the help! Tommy

    Read the article

  • Exclude subdirectory from rewrite rule in web.config

    - by Clog
    This question comes up often, but I can only find solutions for PHP, Apache, htaccess etc but not for web.config I would like my pages to return in HTTP not HTTPS, except for forms within certain subdirectories. I have created the following web.config file, but how do I exclude a subdirectory called forms. <configuration> <system.webServer> <rewrite> <rules> <rule name="Force all to HTTP" stopProcessing="true"> <match url="(.*)" /> <conditions> <add input="{HTTPS}" pattern="on" ignoreCase="true" /> </conditions> <action type="Redirect" redirectType="Found" url="http://www.mysite.com/{R:1}" /> </rule> </rules> </rewrite> </system.webServer> </configuration> Many thanks all you clever clogs.

    Read the article

  • C# call a C++ dll get EntryPointNotFoundException

    - by 5YrsLaterDBA
    I was gaven a C++ dll file, a lib file and a header file. I need to call them from my C# application. header file looks like this: class Clog ; class EXPORT_MACRO NB_DPSM { private: string sFileNameToAnalyze ; Clog *pLog ; void write2log(string text) ; public: NB_DPSM(void); ~NB_DPSM(void); void setFileNameToAnalyze(string FileNameToAnalyze) ; int WriteGenbenchData(string& message) ; }; In my C# code, I have those code: internal ReturnStatus correctDataDLL(string rawDataFileName) { if (rawDataFileName == null || rawDataFileName.Length <= 0) { return ReturnStatus.Return_CannotFindFile; } else { setFileNameToAnalyze(rawDataFileName); } string msg = ""; int returnVal = WriteGenbenchData(ref msg); return ReturnStatus.Return_Success; } [DllImport("..\\..\\thirdParty\\cogs\\NB_DPSM.dll")] public static extern void setFileNameToAnalyze(string fileName); [DllImport("..\\..\\thirdParty\\cogs\\NB_DPSM.dll")] public static extern int WriteGenbenchData(ref string message); I got EntryPointNotFoundException at the setFileNameToAnalyze(rawDataFileName); statement. Few questions: do I need to add that lib file into somewhere of my C# project? how? do I need to add the header file into my C# project? how? (no compile error for now) I would like to remove those "..\\..\\thirdParty\\cogs\\" hardcode path. how to this? how to get ride of that EntryPointNotFoundException? thanks,

    Read the article

  • pfsense log file retention

    - by Colin Pickard
    We have a pfSense firewall in our datacentre. By default, pfSense is only storing 500K of firewall filter logs, which is only a few hours for us. How can I increase this? pfSense uses clog rather than the usual BSD newsyslog. I only want the log for debugging firewall rules, not compliance or anything, and the firewall has 100GB of spare disk space, so I'd rather have the logs on the firewall itself than set up a syslog server.

    Read the article

  • pfsense log file retention

    - by Colin Pickard
    We have a pfSense firewall in our datacentre. By default, pfSense is only storing 500K of firewall filter logs, which is only a few hours for us. How can I increase this? pfSense uses clog rather than the usual BSD newsyslog. I only want the log for debugging firewall rules, not compliance or anything, and the firewall has 100GB of spare disk space, so I'd rather have the logs on the firewall itself than set up a syslog server.

    Read the article

  • Programming Interview : How to debug a program?

    - by Jake
    I was recently asked the following question in an interview : How do you debug a C++ program ? I started by explaining that programs may have syntax and semantic errors. Compiler reports the syntax errors which can be corrected. For semantic errors, various debuggers are available. I specifically talked about gdb, which is command line, and Visual Studio IDE's debugger, which has a GUI, and common commands. I also talked about debug and release version of code, how assertions should be used for debug build, how exceptions helps in automatic cleanup & putting the program in valid state, and how logging can be useful (e.g. using std::clog). I want to know if this answer is complete or not. Also, I want to hear how other people will go about answering this question in a structured manner ? Thanks.

    Read the article

  • How do I retrieve program output in Python?

    - by Geoff
    I'm not a Perl user, but from this question deduced that it's exceedingly easy to retrieve the standard output of a program executed through a Perl script using something akin to: $version = `java -version`; How would I go about getting the same end result in Python? Does the above line retrieve standard error (equivalent to C++ std::cerr) and standard log (std::clog) output as well? If not, how can I retrieve those output streams as well? Thanks, Geoff

    Read the article

  • how to open many tabs in chromium but unload/disable inactive/notCurrent ones, releasing memory and cpu?

    - by Aquarius Power
    So I have 50 tabs opened on chromium, but that is using too much memory and some of the CPU. How can I have all those concurrent researches I am doing opened but not clog my machine? I think there should have a way that only the active tab is loaded in memory and running, and all the others should stay closed/unloaded from memory, until I want to look at them... Any extension can do something like that?

    Read the article

  • How to view only Mail on shared email account?

    - by TomatoSandwich
    I have a support account which I should have access to in my Outlook 2010, however, since changing from 2003, the situation has become unusual. I used to be able to just view shared mail items in a seperate account, without it having the Calendar, Tasks and Reminders popping up in my face all hours of the day. Now, if I add the account, I get upwards of 60 task reminders that are not my personal account, and that clog up my Reminders window and task list. Is there a way to show only my Tasks and Reminders in Outlook 2010? I've tried the Advanced Filter option on the Tasks list, but if I set it to show only things from or to myself, everything disappears, or nothing disappears. I tried looking in the email account settings for something like 'Read email only' or something to do with only showing some of the modules of outlook, but it was useless.

    Read the article

  • How to remove IMAP account from Thunderbird's "Grouped Inbox"

    - by Pekka
    I have four IMAP accounts "merged" into one using Thunderbird 2's "Grouped inbox" view. I want to take one of the four accounts out of the grouped view. It is a maintenance mailbox that contains a lot of status mails. Those mails tend to clog my "real" inbox. I am able to edit the Inbox folder using "Properties". In the list that comes up, it is possible to de-select the maintenance mailbox and everything works fine. However, if I restart Thunderbird, it will forget what I de-selected and use all four mailboxes again. Is there any way to make Thunderbird remember the change?

    Read the article

  • Thunderbird's Grouped Inbox always shows all accounts

    - by Pekka
    I have four IMAP accounts "merged" into one using Thunderbird 2's "Grouped inbox" view. I want to take one of the four accounts out of the grouped view. It is a maintenance mailbox that contains a lot of status mails. Those mails tend to clog my "real" inbox. I am able to edit the Inbox folder using "Properties". In the list that comes up, it is possible to de-select the maintenance mailbox and everything works fine. However, if I restart Thunderbird, it will forget what I de-selected and use all four mailboxes again. Is there any way to make Thunderbird remember the change?

    Read the article

  • you will see the ugg boots outlet of type, color, size

    - by skhtyu skhtyu
    These humans taken the apple through hurricane. Lots added humans accompany in their friends' traces to use these affidavit footwear, they are fabricated from top-grade Foreign merino uggs for cheap. Amazing abundance and aswell amore tend to be assured aloft accustomed materials.bailey button uggs which are at aboriginal acclimated by Australian accept set off a abnormality all over the apple these days. plenty of celebrities are usually spotted putting them on purple uggs this aswell allures abounding individuals to get. For those who alarm for to access due to the fact, go to internet vendors & they can accepting superior twos awash with affordable prices adapted now there.When researching arrangement pink uggs through web food or arrangement sites, ensure to see their own go aback and aswell acquittance procedures afore you achieve your choice. So as you will see the advantage of type, color, admeasurement as able-bodied as absolute acclimated seems to be amaranthine and now application the accession of the uggs cheap and a clog up adaptation you're a lot added ashore for choice. So no amount what, the absolute "in" affair for your chiffonier this advancing year is in achievement affected ugg classic short for ladies, and you're artlessly abiding to acquisition a brace that's aural your budget.

    Read the article

  • Silverlight error-handling conventions: There is no relationship between onSilverlightError and Repo

    - by rasx
    When I see the call System.Windows.Browser.HtmlPage.Window.Eval (which is evil) in ReportErrorToDOM (in App.xaml.cs) this shows me that it has no relationship to onSilverlightError. So what kind of JavaScript-based scenario calls onSilverlightError? When will onSilverlightError definitely be needed? What are Silverlight error-handling conventions in general? This is a very important comment by Erik Monk but needs more detail: There are 2 kinds of terminal errors in Silverlight. 1) Managed errors (hit the managed Application_UnhandledException method). Note that some errors may not even get to this point. If the managed infrastructure can't be loaded for some reason (out of memory error maybe...), you won't get this kind of error. Still, if you can get it, you can use a web service (or the CLOG project) to communicate it back to the server. 2) Javascript errors.

    Read the article

  • ASP.NET - remote screenshot

    - by ufoq
    Hi All, I made a very very simple small app to take screenshot of the desktop and send to network share. About 10 PC's would have this app installed. My idea is, that there will be one dashboard in ASP.NET, which simply shows those screenshots on the webpage. So far, easy stuff. But, because I don't want to clog the network and send the screenshot every 1 minute, I would like to launch the .exe on the remote PC's by demand of ASP.NET user. Unfortunately I haven't found any information (and I'm a complete ASP.NET n00b), how to launch remote executable IN the context of the remote PC (so I won't see screenshots of ASP server :) ) If there is no such possibility, please advise about other way to solve this.

    Read the article

  • I'm creating my own scalable, rapid prototyping web server. How should I design it?

    - by Mike Willliams
    I'm going to create my own web server that focuses on scalability, rapid prototyping and the use of JavaScript as the server's scripting language, much like node.js. It will use a Model-View-Controller design pattern so a web application can support more concurrent users just by adding hardware -- and not having to redesign the software. Basically, I'm aiming to produce a framework that allows for fast and easy development of cloud applications without the need to write lots of boiler plate code. I've got some questions about this... How hard will it be to put MySQL in the cloud? How could I go about implementing this and make the resulting product free? Will I have to write my own engine or modify an existing one, if I do what should I watch out for? To make this scalable I need to adjust from one server to hundreds of servers this creates the requirement for the servers to be load balancing, how should I do this? If I balance based on the work load per server I would need gateway to handle all the incoming requests. Is it the right idea to have all the servers check into the gateway and update there status. By having the servers run through a gateway if the gateway dies all the incoming requests are ignored. I'm thinking that having all the servers maintain a list of each other, or at least a few I could rebuild the list of servers and establish a new gateway. Is it worth it? Or should I have a backup gateway that could switch out? Should I let the user choose? How should I pick which server handles the database and which handles the page serving? Should I spread the database so that queries are preformed on multiple servers? Which would theoretically improve performance. The servers would need to mirror the database at least once so that if a server goes down the database isn't corrupted. So this brings up writing another question, should I broadcast SQL queries so that all the servers can take a bit of the work load? If I do it that way wouldn't a query clog up the network so that other queries couldn't be preformed? What are my alternatives? Finally, is there a free solution already out there that might need a little modification that suits my needs?

    Read the article

  • rsnapshot schedule overlapping, help with backup schedule

    - by Znarkus
    Hello, I have to following configuration. rsnapshot.conf interval halfhourly 4 interval hourly 6 interval twohourly 12 interval daily 7 interval weekly 4 crontab 0,30 * * * * /usr/bin/rsnapshot halfhourly >> /var/log/rsnapshot.halfhourly.log 2>&1 5 * * * * /usr/bin/rsnapshot hourly >> /var/log/rsnapshot.hourly.log 2>&1 10 */2 * * * /usr/bin/rsnapshot twohourly >> /var/log/rsnapshot.twohourly.log 2>&1 15 3 * * * /usr/bin/rsnapshot daily >> /var/log/rsnapshot.daily.log 2>&1 20 6 * * MON /usr/bin/rsnapshot weekly >> /var/log/rsnapshot.weekly.log 2>&1 Only halfhourly is running correctly now. hourly spits out this error: rsnapshot encountered an error! The program was invoked with these options: /usr/bin/rsnapshot hourly ---------------------------------------------------------------------------- ERROR: Lockfile /var/run/rsnapshot.pid exists and so does its process, can not continue To me it seems like my 5 min space between halfhourly and hourly is too small. Is this configuration crazy? I like having backups every thirty minutes, that will probably save my ass some day. Please help me make a decent backup schedule, that doesn't clog up the system, but creates frequent enough backups. Thank you.

    Read the article

  • Install GIMP 2.7.1 on Lucid Lynx using PPA

    - by Vivek
    GIMP lovers are going to be disappointed to hear that GIMP is going away in the next release of much awaited Ubuntu 10.04. Today we take a look at installing in on Lucid Lynx using PPA. The reason for getting rid of it as cited by the GIMP developers, is that GIMP is too professional a software to be included in regular desktop version of Ubuntu. And it takes up too much of space on the disk. Also, the fact that it’s too complicated for regular users. If you can’t live without it…let’s see how to install GIMP 2.7.1 on Lucid Lynx (Currently in Alpha). The new version of GIMP supports single window mode and we will also see how to enable this feature as well. First we need to add the official GIMP 2.7.1 PPA in the software sources of Ubuntu 10.04, by opening the terminal window and typing the following command: sudo sh -c “echo ‘deb http://ppa.launchpad.net/matthaeus123/mrw-gimp-svn/ubuntu lucid main’ >> /etc/apt/sources.list” Now that we have added the PPA we need to add the GPG key, so type the following in your Terminal window. sudo apt-key adv –recv-keys –keyserver keyserver.ubuntu.com 405A15CB Next up we have to update the software repository… sudo apt-get update All that is left is to install GIMP 2.7.1 by typing in the following… sudo apt-get install gimp Click ‘Y’ (for yes) to install GIMP Once GIMP is installed you can start it by going to Applications > Graphics > GNU Image Manipulation Program. You now have your favorite GIMP on your favorite Ubuntu 10.04. As you can see in the image below, GIMP still comes with default 3 windows, which could clog up your lower panel In Ubuntu 10.04. However, now you can run GIMP in single window mode by going to Windows > Single-Window mode. That’s all! Now you have your GIMP running in single window mode with less of hassle to manage 3 windows. It’s unfortunate that GIMP will not be included, but by following these instructions, you’ll be able to enjoy using it in Ubuntu 10.04. Similar Articles Productive Geek Tips Show the List of Installed Packages on Ubuntu or DebianHow to Install Windows Applications on Linux Using CrossoverInstall VMware Tools on Ubuntu Edgy EftInstall Adobe PDF Reader on Ubuntu EdgyInstall MySQL Server 4.1 on Ubuntu TouchFreeze Alternative in AutoHotkey The Icy Undertow Desktop Windows Home Server – Backup to LAN The Clear & Clean Desktop Use This Bookmarklet to Easily Get Albums Use AutoHotkey to Assign a Hotkey to a Specific Window Latest Software Reviews Tinyhacker Random Tips Revo Uninstaller Pro Registry Mechanic 9 for Windows PC Tools Internet Security Suite 2010 PCmover Professional Stretch popurls.com with a Stylish Script (Firefox) OldTvShows.org – Find episodes of Hitchcock, Soaps, Game Shows and more Download Microsoft Office Help tab The Growth of Citibank Quickly Switch between Tabs in IE Windows Media Player 12: Tweak Video & Sound with Playback Enhancements

    Read the article

  • memory leak in php script

    - by Jasper De Bruijn
    Hi, I have a php script that runs a mysql query, then loops the result, and in that loop also runs several queries: $sqlstr = "SELECT * FROM user_pred WHERE uprType != 2 AND uprTurn=$turn ORDER BY uprUserTeamIdFK"; $utmres = mysql_query($sqlstr) or trigger_error($termerror = __FILE__." - ".__LINE__.": ".mysql_error()); while($utmrow = mysql_fetch_array($utmres, MYSQL_ASSOC)) { // some stuff happens here // echo memory_get_usage() . " - 1241<br/>\n"; $sqlstr = "UPDATE user_roundscores SET ursUpdDate=NOW(),ursScore=$score WHERE ursUserTeamIdFK=$userteamid"; if(!mysql_query($sqlstr)) { $err_crit++; $cLog->WriteLogFile("Failed to UPDATE user_roundscores record for user $userid - teamuserid: $userteamid\n"); echo "Failed to UPDATE user_roundscores record for user $userid - teamuserid: $userteamid<br>\n"; break; } unset($sqlstr); // echo memory_get_usage() . " - 1253<br/>\n"; // some stuff happens here too } The update query never fails. For some reason, between the two calls of memory_get_usage, there is some memory added. Because the big loop runs about 500.000 or more times, in the end it really adds up to alot of memory. Is there anything I'm missing here? could it herhaps be that the memory is not actually added between the two calls, but at another point in the script? Edit: some extra info: Before the loop it's at about 5mb, after the loop about 440mb, and every update query adds about 250 bytes. (the rest of the memory gets added at other places in the loop). The reason I didn't post more of the "other stuff" is because its about 300 lines of code. I posted this part because it looks to be where the most memory is added.

    Read the article

  • Destroy process-less console windows left by Visual Studio debug sessions

    - by jon hanson
    A known bug with security update KB978037 can occur with Visual Studio 2003 (and 2008) where sometimes if you restart a debugging session on a console app then the console window doesn't get closed even though the owner process no longer exists. The problem is discussed further here: http://stackoverflow.com/questions/2402875/visual-studio-debug-console-sometimes-stays-open-and-is-impossible-to-close These zombie windows then can not be closed via the Taskbar or via the TaskManager, and typically require a power off/on to get rid of them. Over the period of even a single day you can accumulate quite a few of them, which clog up your TaskBar and are generally annoying. I thought I would knock up a simple C++ Win32 utility to attempt to call DestroyWindow() on these windows by passing the windows handle as a cmd-line argument and converting it to a HWND. I'm converting the handle from a string by parsing it as a DWORD then casting the DWORD to a HWND. This appears to be working as if I call GetWindowInfo() on the handle it succeeds. However calling DestroyWindow() on the handle fails with error 5 (access denied), presumably because the caller process (i.e. my app) doesn't own the window in question. Any ideas as to how I might get rid of the zombie windows, either via the above approach or any other alternative short of rebooting? I'm in a corporate environment so installing/uninstalling updates/service-packs etc isn't an option.

    Read the article

  • How to populate a listview in ASP.NET 3.5 through a dataset?

    - by EasyDot
    Is it possible to populate a listview with a dataset? I have a function that returns a dataset. Why im asking this is because my SQL is quite complicated and i can't convert it to a SQLDataSource... Public Function getMessages() As DataSet Dim dSet As DataSet = New DataSet Dim da As SqlDataAdapter Dim cmd As SqlCommand Dim SQL As StringBuilder Dim connStr As StringBuilder = New StringBuilder("") connStr.AppendFormat("server={0};", ConfigurationSettings.AppSettings("USERserver").ToString()) connStr.AppendFormat("database={0};", ConfigurationSettings.AppSettings("USERdb").ToString()) connStr.AppendFormat("uid={0};", ConfigurationSettings.AppSettings("USERuid").ToString()) connStr.AppendFormat("pwd={0};", ConfigurationSettings.AppSettings("USERpwd").ToString()) Dim conn As SqlConnection = New SqlConnection(connStr.ToString()) Try SQL = New StringBuilder cmd = New SqlCommand SQL.Append("SELECT m.MESSAGE_ID, m.SYSTEM_ID, m.DATE_CREATED, m.EXPIRE_DATE, ISNULL(s.SYSTEM_DESC,'ALL SYSTEMS') AS SYSTEM_DESC, m.MESSAGE ") SQL.Append("FROM MESSAGE m ") SQL.Append("LEFT OUTER JOIN [SYSTEM] s ") SQL.Append("ON m.SYSTEM_ID = s.SYSTEM_ID ") SQL.AppendFormat("WHERE m.SYSTEM_ID IN ({0}) ", sSystems) SQL.Append("OR m.SYSTEM_ID is NULL ") SQL.Append("ORDER BY m.DATE_CREATED DESC; ") SQL.Append("SELECT mm.MESSAGE_ID, mm.MODEL_ID, m.MODEL_DESC ") SQL.Append("FROM MESSAGE_MODEL mm ") SQL.Append("JOIN MODEL m ") SQL.Append(" ON m.MODEL_ID = mm.MODEL_ID ") cmd.CommandText = SQL.ToString cmd.Connection = conn da = New SqlDataAdapter(cmd) da.Fill(dSet) dSet.Tables(0).TableName = "BASE" dSet.Tables(1).TableName = "MODEL" Return dSet Catch ev As Exception cLog.EventLog.logError(ev, cmd) Finally 'conn.Close() End Try End Function

    Read the article

  • Why do I get this strange output behavior?

    - by WilliamKF
    I have the following program test.cc: #include <iostream> unsigned char bogus1[] = { // Changing # of periods (0x2e) changes output after periods. 0x2e, 0x2e, 0x2e, 0x2e }; unsigned int bogus2 = 1816; // Changing this value changes output. int main() { std::clog << bogus1; } I build it with: g++ -g -c -o test.o test.cc; g++ -static-libgcc -o test test.o Using g++ version 3.4.6 I run it through valgrind and nothing is reported wrong. However the output has two extra control characters and looks like this: .... Thats a control-X and a control-G at the end. If you change the value of bogus2 you get different control characters. If you change the number of periods in the array the issue goes away or changes. I suspect it is a memory corruption bug in the compiler or iostream package. What is going on here?

    Read the article

  • Using R to Analyze G1GC Log Files

    - by user12620111
    Using R to Analyze G1GC Log Files body, td { font-family: sans-serif; background-color: white; font-size: 12px; margin: 8px; } tt, code, pre { font-family: 'DejaVu Sans Mono', 'Droid Sans Mono', 'Lucida Console', Consolas, Monaco, monospace; } h1 { font-size:2.2em; } h2 { font-size:1.8em; } h3 { font-size:1.4em; } h4 { font-size:1.0em; } h5 { font-size:0.9em; } h6 { font-size:0.8em; } a:visited { color: rgb(50%, 0%, 50%); } pre { margin-top: 0; max-width: 95%; border: 1px solid #ccc; white-space: pre-wrap; } pre code { display: block; padding: 0.5em; } code.r, code.cpp { background-color: #F8F8F8; } table, td, th { border: none; } blockquote { color:#666666; margin:0; padding-left: 1em; border-left: 0.5em #EEE solid; } hr { height: 0px; border-bottom: none; border-top-width: thin; border-top-style: dotted; border-top-color: #999999; } @media print { * { background: transparent !important; color: black !important; filter:none !important; -ms-filter: none !important; } body { font-size:12pt; max-width:100%; } a, a:visited { text-decoration: underline; } hr { visibility: hidden; page-break-before: always; } pre, blockquote { padding-right: 1em; page-break-inside: avoid; } tr, img { page-break-inside: avoid; } img { max-width: 100% !important; } @page :left { margin: 15mm 20mm 15mm 10mm; } @page :right { margin: 15mm 10mm 15mm 20mm; } p, h2, h3 { orphans: 3; widows: 3; } h2, h3 { page-break-after: avoid; } } pre .operator, pre .paren { color: rgb(104, 118, 135) } pre .literal { color: rgb(88, 72, 246) } pre .number { color: rgb(0, 0, 205); } pre .comment { color: rgb(76, 136, 107); } pre .keyword { color: rgb(0, 0, 255); } pre .identifier { color: rgb(0, 0, 0); } pre .string { color: rgb(3, 106, 7); } var hljs=new function(){function m(p){return p.replace(/&/gm,"&").replace(/"}while(y.length||w.length){var v=u().splice(0,1)[0];z+=m(x.substr(q,v.offset-q));q=v.offset;if(v.event=="start"){z+=t(v.node);s.push(v.node)}else{if(v.event=="stop"){var p,r=s.length;do{r--;p=s[r];z+=("")}while(p!=v.node);s.splice(r,1);while(r'+M[0]+""}else{r+=M[0]}O=P.lR.lastIndex;M=P.lR.exec(L)}return r+L.substr(O,L.length-O)}function J(L,M){if(M.sL&&e[M.sL]){var r=d(M.sL,L);x+=r.keyword_count;return r.value}else{return F(L,M)}}function I(M,r){var L=M.cN?'':"";if(M.rB){y+=L;M.buffer=""}else{if(M.eB){y+=m(r)+L;M.buffer=""}else{y+=L;M.buffer=r}}D.push(M);A+=M.r}function G(N,M,Q){var R=D[D.length-1];if(Q){y+=J(R.buffer+N,R);return false}var P=q(M,R);if(P){y+=J(R.buffer+N,R);I(P,M);return P.rB}var L=v(D.length-1,M);if(L){var O=R.cN?"":"";if(R.rE){y+=J(R.buffer+N,R)+O}else{if(R.eE){y+=J(R.buffer+N,R)+O+m(M)}else{y+=J(R.buffer+N+M,R)+O}}while(L1){O=D[D.length-2].cN?"":"";y+=O;L--;D.length--}var r=D[D.length-1];D.length--;D[D.length-1].buffer="";if(r.starts){I(r.starts,"")}return R.rE}if(w(M,R)){throw"Illegal"}}var E=e[B];var D=[E.dM];var A=0;var x=0;var y="";try{var s,u=0;E.dM.buffer="";do{s=p(C,u);var t=G(s[0],s[1],s[2]);u+=s[0].length;if(!t){u+=s[1].length}}while(!s[2]);if(D.length1){throw"Illegal"}return{r:A,keyword_count:x,value:y}}catch(H){if(H=="Illegal"){return{r:0,keyword_count:0,value:m(C)}}else{throw H}}}function g(t){var p={keyword_count:0,r:0,value:m(t)};var r=p;for(var q in e){if(!e.hasOwnProperty(q)){continue}var s=d(q,t);s.language=q;if(s.keyword_count+s.rr.keyword_count+r.r){r=s}if(s.keyword_count+s.rp.keyword_count+p.r){r=p;p=s}}if(r.language){p.second_best=r}return p}function i(r,q,p){if(q){r=r.replace(/^((]+|\t)+)/gm,function(t,w,v,u){return w.replace(/\t/g,q)})}if(p){r=r.replace(/\n/g,"")}return r}function n(t,w,r){var x=h(t,r);var v=a(t);var y,s;if(v){y=d(v,x)}else{return}var q=c(t);if(q.length){s=document.createElement("pre");s.innerHTML=y.value;y.value=k(q,c(s),x)}y.value=i(y.value,w,r);var u=t.className;if(!u.match("(\\s|^)(language-)?"+v+"(\\s|$)")){u=u?(u+" "+v):v}if(/MSIE [678]/.test(navigator.userAgent)&&t.tagName=="CODE"&&t.parentNode.tagName=="PRE"){s=t.parentNode;var p=document.createElement("div");p.innerHTML=""+y.value+"";t=p.firstChild.firstChild;p.firstChild.cN=s.cN;s.parentNode.replaceChild(p.firstChild,s)}else{t.innerHTML=y.value}t.className=u;t.result={language:v,kw:y.keyword_count,re:y.r};if(y.second_best){t.second_best={language:y.second_best.language,kw:y.second_best.keyword_count,re:y.second_best.r}}}function o(){if(o.called){return}o.called=true;var r=document.getElementsByTagName("pre");for(var p=0;p|=||=||=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.ER="(?![\\s\\S])";this.BE={b:"\\\\.",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.inherit=function(r,s){var p={};for(var q in r){p[q]=r[q]}if(s){for(var q in s){p[q]=s[q]}}return p}}();hljs.LANGUAGES.cpp=function(){var a={keyword:{"false":1,"int":1,"float":1,"while":1,"private":1,"char":1,"catch":1,"export":1,virtual:1,operator:2,sizeof:2,dynamic_cast:2,typedef:2,const_cast:2,"const":1,struct:1,"for":1,static_cast:2,union:1,namespace:1,unsigned:1,"long":1,"throw":1,"volatile":2,"static":1,"protected":1,bool:1,template:1,mutable:1,"if":1,"public":1,friend:2,"do":1,"return":1,"goto":1,auto:1,"void":2,"enum":1,"else":1,"break":1,"new":1,extern:1,using:1,"true":1,"class":1,asm:1,"case":1,typeid:1,"short":1,reinterpret_cast:2,"default":1,"double":1,register:1,explicit:1,signed:1,typename:1,"try":1,"this":1,"switch":1,"continue":1,wchar_t:1,inline:1,"delete":1,alignof:1,char16_t:1,char32_t:1,constexpr:1,decltype:1,noexcept:1,nullptr:1,static_assert:1,thread_local:1,restrict:1,_Bool:1,complex:1},built_in:{std:1,string:1,cin:1,cout:1,cerr:1,clog:1,stringstream:1,istringstream:1,ostringstream:1,auto_ptr:1,deque:1,list:1,queue:1,stack:1,vector:1,map:1,set:1,bitset:1,multiset:1,multimap:1,unordered_set:1,unordered_map:1,unordered_multiset:1,unordered_multimap:1,array:1,shared_ptr:1}};return{dM:{k:a,i:"",k:a,r:10,c:["self"]}]}}}();hljs.LANGUAGES.r={dM:{c:[hljs.HCM,{cN:"number",b:"\\b0[xX][0-9a-fA-F]+[Li]?\\b",e:hljs.IMMEDIATE_RE,r:0},{cN:"number",b:"\\b\\d+(?:[eE][+\\-]?\\d*)?L\\b",e:hljs.IMMEDIATE_RE,r:0},{cN:"number",b:"\\b\\d+\\.(?!\\d)(?:i\\b)?",e:hljs.IMMEDIATE_RE,r:1},{cN:"number",b:"\\b\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",e:hljs.IMMEDIATE_RE,r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",e:hljs.IMMEDIATE_RE,r:1},{cN:"keyword",b:"(?:tryCatch|library|setGeneric|setGroupGeneric)\\b",e:hljs.IMMEDIATE_RE,r:10},{cN:"keyword",b:"\\.\\.\\.",e:hljs.IMMEDIATE_RE,r:10},{cN:"keyword",b:"\\.\\.\\d+(?![\\w.])",e:hljs.IMMEDIATE_RE,r:10},{cN:"keyword",b:"\\b(?:function)",e:hljs.IMMEDIATE_RE,r:2},{cN:"keyword",b:"(?:if|in|break|next|repeat|else|for|return|switch|while|try|stop|warning|require|attach|detach|source|setMethod|setClass)\\b",e:hljs.IMMEDIATE_RE,r:1},{cN:"literal",b:"(?:NA|NA_integer_|NA_real_|NA_character_|NA_complex_)\\b",e:hljs.IMMEDIATE_RE,r:10},{cN:"literal",b:"(?:NULL|TRUE|FALSE|T|F|Inf|NaN)\\b",e:hljs.IMMEDIATE_RE,r:1},{cN:"identifier",b:"[a-zA-Z.][a-zA-Z0-9._]*\\b",e:hljs.IMMEDIATE_RE,r:0},{cN:"operator",b:"|=||   Using R to Analyze G1GC Log Files   Using R to Analyze G1GC Log Files Introduction Working in Oracle Platform Integration gives an engineer opportunities to work on a wide array of technologies. My team’s goal is to make Oracle applications run best on the Solaris/SPARC platform. When looking for bottlenecks in a modern applications, one needs to be aware of not only how the CPUs and operating system are executing, but also network, storage, and in some cases, the Java Virtual Machine. I was recently presented with about 1.5 GB of Java Garbage First Garbage Collector log file data. If you’re not familiar with the subject, you might want to review Garbage First Garbage Collector Tuning by Monica Beckwith. The customer had been running Java HotSpot 1.6.0_31 to host a web application server. I was told that the Solaris/SPARC server was running a Java process launched using a commmand line that included the following flags: -d64 -Xms9g -Xmx9g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=80 -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+PrintGC -XX:+PrintGCTimeStamps -XX:+PrintHeapAtGC -XX:+PrintGCDateStamps -XX:+PrintFlagsFinal -XX:+DisableExplicitGC -XX:+UnlockExperimentalVMOptions -XX:ParallelGCThreads=8 Several sources on the internet indicate that if I were to print out the 1.5 GB of log files, it would require enough paper to fill the bed of a pick up truck. Of course, it would be fruitless to try to scan the log files by hand. Tools will be required to summarize the contents of the log files. Others have encountered large Java garbage collection log files. There are existing tools to analyze the log files: IBM’s GC toolkit The chewiebug GCViewer gchisto HPjmeter Instead of using one of the other tools listed, I decide to parse the log files with standard Unix tools, and analyze the data with R. Data Cleansing The log files arrived in two different formats. I guess that the difference is that one set of log files was generated using a more verbose option, maybe -XX:+PrintHeapAtGC, and the other set of log files was generated without that option. Format 1 In some of the log files, the log files with the less verbose format, a single trace, i.e. the report of a singe garbage collection event, looks like this: {Heap before GC invocations=12280 (full 61): garbage-first heap total 9437184K, used 7499918K [0xfffffffd00000000, 0xffffffff40000000, 0xffffffff40000000) region size 4096K, 1 young (4096K), 0 survivors (0K) compacting perm gen total 262144K, used 144077K [0xffffffff40000000, 0xffffffff50000000, 0xffffffff50000000) the space 262144K, 54% used [0xffffffff40000000, 0xffffffff48cb3758, 0xffffffff48cb3800, 0xffffffff50000000) No shared spaces configured. 2014-05-14T07:24:00.988-0700: 60586.353: [GC pause (young) 7324M->7320M(9216M), 0.1567265 secs] Heap after GC invocations=12281 (full 61): garbage-first heap total 9437184K, used 7496533K [0xfffffffd00000000, 0xffffffff40000000, 0xffffffff40000000) region size 4096K, 0 young (0K), 0 survivors (0K) compacting perm gen total 262144K, used 144077K [0xffffffff40000000, 0xffffffff50000000, 0xffffffff50000000) the space 262144K, 54% used [0xffffffff40000000, 0xffffffff48cb3758, 0xffffffff48cb3800, 0xffffffff50000000) No shared spaces configured. } A simple grep can be used to extract a summary: $ grep "\[ GC pause (young" g1gc.log 2014-05-13T13:24:35.091-0700: 3.109: [GC pause (young) 20M->5029K(9216M), 0.0146328 secs] 2014-05-13T13:24:35.440-0700: 3.459: [GC pause (young) 9125K->6077K(9216M), 0.0086723 secs] 2014-05-13T13:24:37.581-0700: 5.599: [GC pause (young) 25M->8470K(9216M), 0.0203820 secs] 2014-05-13T13:24:42.686-0700: 10.704: [GC pause (young) 44M->15M(9216M), 0.0288848 secs] 2014-05-13T13:24:48.941-0700: 16.958: [GC pause (young) 51M->20M(9216M), 0.0491244 secs] 2014-05-13T13:24:56.049-0700: 24.066: [GC pause (young) 92M->26M(9216M), 0.0525368 secs] 2014-05-13T13:25:34.368-0700: 62.383: [GC pause (young) 602M->68M(9216M), 0.1721173 secs] But that format wasn't easily read into R, so I needed to be a bit more tricky. I used the following Unix command to create a summary file that was easy for R to read. $ echo "SecondsSinceLaunch BeforeSize AfterSize TotalSize RealTime" $ grep "\[GC pause (young" g1gc.log | grep -v mark | sed -e 's/[A-SU-z\(\),]/ /g' -e 's/->/ /' -e 's/: / /g' | more SecondsSinceLaunch BeforeSize AfterSize TotalSize RealTime 2014-05-13T13:24:35.091-0700 3.109 20 5029 9216 0.0146328 2014-05-13T13:24:35.440-0700 3.459 9125 6077 9216 0.0086723 2014-05-13T13:24:37.581-0700 5.599 25 8470 9216 0.0203820 2014-05-13T13:24:42.686-0700 10.704 44 15 9216 0.0288848 2014-05-13T13:24:48.941-0700 16.958 51 20 9216 0.0491244 2014-05-13T13:24:56.049-0700 24.066 92 26 9216 0.0525368 2014-05-13T13:25:34.368-0700 62.383 602 68 9216 0.1721173 Format 2 In some of the log files, the log files with the more verbose format, a single trace, i.e. the report of a singe garbage collection event, was more complicated than Format 1. Here is a text file with an example of a single G1GC trace in the second format. As you can see, it is quite complicated. It is nice that there is so much information available, but the level of detail can be overwhelming. I wrote this awk script (download) to summarize each trace on a single line. #!/usr/bin/env awk -f BEGIN { printf("SecondsSinceLaunch IncrementalCount FullCount UserTime SysTime RealTime BeforeSize AfterSize TotalSize\n") } ###################### # Save count data from lines that are at the start of each G1GC trace. # Each trace starts out like this: # {Heap before GC invocations=14 (full 0): # garbage-first heap total 9437184K, used 325496K [0xfffffffd00000000, 0xffffffff40000000, 0xffffffff40000000) ###################### /{Heap.*full/{ gsub ( "\\)" , "" ); nf=split($0,a,"="); split(a[2],b," "); getline; if ( match($0, "first") ) { G1GC=1; IncrementalCount=b[1]; FullCount=substr( b[3], 1, length(b[3])-1 ); } else { G1GC=0; } } ###################### # Pull out time stamps that are in lines with this format: # 2014-05-12T14:02:06.025-0700: 94.312: [GC pause (young), 0.08870154 secs] ###################### /GC pause/ { DateTime=$1; SecondsSinceLaunch=substr($2, 1, length($2)-1); } ###################### # Heap sizes are in lines that look like this: # [ 4842M->4838M(9216M)] ###################### /\[ .*]$/ { gsub ( "\\[" , "" ); gsub ( "\ \]" , "" ); gsub ( "->" , " " ); gsub ( "\\( " , " " ); gsub ( "\ \)" , " " ); split($0,a," "); if ( split(a[1],b,"M") > 1 ) {BeforeSize=b[1]*1024;} if ( split(a[1],b,"K") > 1 ) {BeforeSize=b[1];} if ( split(a[2],b,"M") > 1 ) {AfterSize=b[1]*1024;} if ( split(a[2],b,"K") > 1 ) {AfterSize=b[1];} if ( split(a[3],b,"M") > 1 ) {TotalSize=b[1]*1024;} if ( split(a[3],b,"K") > 1 ) {TotalSize=b[1];} } ###################### # Emit an output line when you find input that looks like this: # [Times: user=1.41 sys=0.08, real=0.24 secs] ###################### /\[Times/ { if (G1GC==1) { gsub ( "," , "" ); split($2,a,"="); UserTime=a[2]; split($3,a,"="); SysTime=a[2]; split($4,a,"="); RealTime=a[2]; print DateTime,SecondsSinceLaunch,IncrementalCount,FullCount,UserTime,SysTime,RealTime,BeforeSize,AfterSize,TotalSize; G1GC=0; } } The resulting summary is about 25X smaller that the original file, but still difficult for a human to digest. SecondsSinceLaunch IncrementalCount FullCount UserTime SysTime RealTime BeforeSize AfterSize TotalSize ... 2014-05-12T18:36:34.669-0700: 3985.744 561 0 0.57 0.06 0.16 1724416 1720320 9437184 2014-05-12T18:36:34.839-0700: 3985.914 562 0 0.51 0.06 0.19 1724416 1720320 9437184 2014-05-12T18:36:35.069-0700: 3986.144 563 0 0.60 0.04 0.27 1724416 1721344 9437184 2014-05-12T18:36:35.354-0700: 3986.429 564 0 0.33 0.04 0.09 1725440 1722368 9437184 2014-05-12T18:36:35.545-0700: 3986.620 565 0 0.58 0.04 0.17 1726464 1722368 9437184 2014-05-12T18:36:35.726-0700: 3986.801 566 0 0.43 0.05 0.12 1726464 1722368 9437184 2014-05-12T18:36:35.856-0700: 3986.930 567 0 0.30 0.04 0.07 1726464 1723392 9437184 2014-05-12T18:36:35.947-0700: 3987.023 568 0 0.61 0.04 0.26 1727488 1723392 9437184 2014-05-12T18:36:36.228-0700: 3987.302 569 0 0.46 0.04 0.16 1731584 1724416 9437184 Reading the Data into R Once the GC log data had been cleansed, either by processing the first format with the shell script, or by processing the second format with the awk script, it was easy to read the data into R. g1gc.df = read.csv("summary.txt", row.names = NULL, stringsAsFactors=FALSE,sep="") str(g1gc.df) ## 'data.frame': 8307 obs. of 10 variables: ## $ row.names : chr "2014-05-12T14:00:32.868-0700:" "2014-05-12T14:00:33.179-0700:" "2014-05-12T14:00:33.677-0700:" "2014-05-12T14:00:35.538-0700:" ... ## $ SecondsSinceLaunch: num 1.16 1.47 1.97 3.83 6.1 ... ## $ IncrementalCount : int 0 1 2 3 4 5 6 7 8 9 ... ## $ FullCount : int 0 0 0 0 0 0 0 0 0 0 ... ## $ UserTime : num 0.11 0.05 0.04 0.21 0.08 0.26 0.31 0.33 0.34 0.56 ... ## $ SysTime : num 0.04 0.01 0.01 0.05 0.01 0.06 0.07 0.06 0.07 0.09 ... ## $ RealTime : num 0.02 0.02 0.01 0.04 0.02 0.04 0.05 0.04 0.04 0.06 ... ## $ BeforeSize : int 8192 5496 5768 22528 24576 43008 34816 53248 55296 93184 ... ## $ AfterSize : int 1400 1672 2557 4907 7072 14336 16384 18432 19456 21504 ... ## $ TotalSize : int 9437184 9437184 9437184 9437184 9437184 9437184 9437184 9437184 9437184 9437184 ... head(g1gc.df) ## row.names SecondsSinceLaunch IncrementalCount ## 1 2014-05-12T14:00:32.868-0700: 1.161 0 ## 2 2014-05-12T14:00:33.179-0700: 1.472 1 ## 3 2014-05-12T14:00:33.677-0700: 1.969 2 ## 4 2014-05-12T14:00:35.538-0700: 3.830 3 ## 5 2014-05-12T14:00:37.811-0700: 6.103 4 ## 6 2014-05-12T14:00:41.428-0700: 9.720 5 ## FullCount UserTime SysTime RealTime BeforeSize AfterSize TotalSize ## 1 0 0.11 0.04 0.02 8192 1400 9437184 ## 2 0 0.05 0.01 0.02 5496 1672 9437184 ## 3 0 0.04 0.01 0.01 5768 2557 9437184 ## 4 0 0.21 0.05 0.04 22528 4907 9437184 ## 5 0 0.08 0.01 0.02 24576 7072 9437184 ## 6 0 0.26 0.06 0.04 43008 14336 9437184 Basic Statistics Once the data has been read into R, simple statistics are very easy to generate. All of the numbers from high school statistics are available via simple commands. For example, generate a summary of every column: summary(g1gc.df) ## row.names SecondsSinceLaunch IncrementalCount FullCount ## Length:8307 Min. : 1 Min. : 0 Min. : 0.0 ## Class :character 1st Qu.: 9977 1st Qu.:2048 1st Qu.: 0.0 ## Mode :character Median :12855 Median :4136 Median : 12.0 ## Mean :12527 Mean :4156 Mean : 31.6 ## 3rd Qu.:15758 3rd Qu.:6262 3rd Qu.: 61.0 ## Max. :55484 Max. :8391 Max. :113.0 ## UserTime SysTime RealTime BeforeSize ## Min. :0.040 Min. :0.0000 Min. : 0.0 Min. : 5476 ## 1st Qu.:0.470 1st Qu.:0.0300 1st Qu.: 0.1 1st Qu.:5137920 ## Median :0.620 Median :0.0300 Median : 0.1 Median :6574080 ## Mean :0.751 Mean :0.0355 Mean : 0.3 Mean :5841855 ## 3rd Qu.:0.920 3rd Qu.:0.0400 3rd Qu.: 0.2 3rd Qu.:7084032 ## Max. :3.370 Max. :1.5600 Max. :488.1 Max. :8696832 ## AfterSize TotalSize ## Min. : 1380 Min. :9437184 ## 1st Qu.:5002752 1st Qu.:9437184 ## Median :6559744 Median :9437184 ## Mean :5785454 Mean :9437184 ## 3rd Qu.:7054336 3rd Qu.:9437184 ## Max. :8482816 Max. :9437184 Q: What is the total amount of User CPU time spent in garbage collection? sum(g1gc.df$UserTime) ## [1] 6236 As you can see, less than two hours of CPU time was spent in garbage collection. Is that too much? To find the percentage of time spent in garbage collection, divide the number above by total_elapsed_time*CPU_count. In this case, there are a lot of CPU’s and it turns out the the overall amount of CPU time spent in garbage collection isn’t a problem when viewed in isolation. When calculating rates, i.e. events per unit time, you need to ask yourself if the rate is homogenous across the time period in the log file. Does the log file include spikes of high activity that should be separately analyzed? Averaging in data from nights and weekends with data from business hours may alias problems. If you have a reason to suspect that the garbage collection rates include peaks and valleys that need independent analysis, see the “Time Series” section, below. Q: How much garbage is collected on each pass? The amount of heap space that is recovered per GC pass is surprisingly low: At least one collection didn’t recover any data. (“Min.=0”) 25% of the passes recovered 3MB or less. (“1st Qu.=3072”) Half of the GC passes recovered 4MB or less. (“Median=4096”) The average amount recovered was 56MB. (“Mean=56390”) 75% of the passes recovered 36MB or less. (“3rd Qu.=36860”) At least one pass recovered 2GB. (“Max.=2121000”) g1gc.df$Delta = g1gc.df$BeforeSize - g1gc.df$AfterSize summary(g1gc.df$Delta) ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 0 3070 4100 56400 36900 2120000 Q: What is the maximum User CPU time for a single collection? The worst garbage collection (“Max.”) is many standard deviations away from the mean. The data appears to be right skewed. summary(g1gc.df$UserTime) ## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 0.040 0.470 0.620 0.751 0.920 3.370 sd(g1gc.df$UserTime) ## [1] 0.3966 Basic Graphics Once the data is in R, it is trivial to plot the data with formats including dot plots, line charts, bar charts (simple, stacked, grouped), pie charts, boxplots, scatter plots histograms, and kernel density plots. Histogram of User CPU Time per Collection I don't think that this graph requires any explanation. hist(g1gc.df$UserTime, main="User CPU Time per Collection", xlab="Seconds", ylab="Frequency") Box plot to identify outliers When the initial data is viewed with a box plot, you can see the one crazy outlier in the real time per GC. Save this data point for future analysis and drop the outlier so that it’s not throwing off our statistics. Now the box plot shows many outliers, which will be examined later, using times series analysis. Notice that the scale of the x-axis changes drastically once the crazy outlier is removed. par(mfrow=c(2,1)) boxplot(g1gc.df$UserTime,g1gc.df$SysTime,g1gc.df$RealTime, main="Box Plot of Time per GC\n(dominated by a crazy outlier)", names=c("usr","sys","elapsed"), xlab="Seconds per GC", ylab="Time (Seconds)", horizontal = TRUE, outcol="red") crazy.outlier.df=g1gc.df[g1gc.df$RealTime > 400,] g1gc.df=g1gc.df[g1gc.df$RealTime < 400,] boxplot(g1gc.df$UserTime,g1gc.df$SysTime,g1gc.df$RealTime, main="Box Plot of Time per GC\n(crazy outlier excluded)", names=c("usr","sys","elapsed"), xlab="Seconds per GC", ylab="Time (Seconds)", horizontal = TRUE, outcol="red") box(which = "outer", lty = "solid") Here is the crazy outlier for future analysis: crazy.outlier.df ## row.names SecondsSinceLaunch IncrementalCount ## 8233 2014-05-12T23:15:43.903-0700: 20741 8316 ## FullCount UserTime SysTime RealTime BeforeSize AfterSize TotalSize ## 8233 112 0.55 0.42 488.1 8381440 8235008 9437184 ## Delta ## 8233 146432 R Time Series Data To analyze the garbage collection as a time series, I’ll use Z’s Ordered Observations (zoo). “zoo is the creator for an S3 class of indexed totally ordered observations which includes irregular time series.” require(zoo) ## Loading required package: zoo ## ## Attaching package: 'zoo' ## ## The following objects are masked from 'package:base': ## ## as.Date, as.Date.numeric head(g1gc.df[,1]) ## [1] "2014-05-12T14:00:32.868-0700:" "2014-05-12T14:00:33.179-0700:" ## [3] "2014-05-12T14:00:33.677-0700:" "2014-05-12T14:00:35.538-0700:" ## [5] "2014-05-12T14:00:37.811-0700:" "2014-05-12T14:00:41.428-0700:" options("digits.secs"=3) times=as.POSIXct( g1gc.df[,1], format="%Y-%m-%dT%H:%M:%OS%z:") g1gc.z = zoo(g1gc.df[,-c(1)], order.by=times) head(g1gc.z) ## SecondsSinceLaunch IncrementalCount FullCount ## 2014-05-12 17:00:32.868 1.161 0 0 ## 2014-05-12 17:00:33.178 1.472 1 0 ## 2014-05-12 17:00:33.677 1.969 2 0 ## 2014-05-12 17:00:35.538 3.830 3 0 ## 2014-05-12 17:00:37.811 6.103 4 0 ## 2014-05-12 17:00:41.427 9.720 5 0 ## UserTime SysTime RealTime BeforeSize AfterSize ## 2014-05-12 17:00:32.868 0.11 0.04 0.02 8192 1400 ## 2014-05-12 17:00:33.178 0.05 0.01 0.02 5496 1672 ## 2014-05-12 17:00:33.677 0.04 0.01 0.01 5768 2557 ## 2014-05-12 17:00:35.538 0.21 0.05 0.04 22528 4907 ## 2014-05-12 17:00:37.811 0.08 0.01 0.02 24576 7072 ## 2014-05-12 17:00:41.427 0.26 0.06 0.04 43008 14336 ## TotalSize Delta ## 2014-05-12 17:00:32.868 9437184 6792 ## 2014-05-12 17:00:33.178 9437184 3824 ## 2014-05-12 17:00:33.677 9437184 3211 ## 2014-05-12 17:00:35.538 9437184 17621 ## 2014-05-12 17:00:37.811 9437184 17504 ## 2014-05-12 17:00:41.427 9437184 28672 Example of Two Benchmark Runs in One Log File The data in the following graph is from a different log file, not the one of primary interest to this article. I’m including this image because it is an example of idle periods followed by busy periods. It would be uninteresting to average the rate of garbage collection over the entire log file period. More interesting would be the rate of garbage collect in the two busy periods. Are they the same or different? Your production data may be similar, for example, bursts when employees return from lunch and idle times on weekend evenings, etc. Once the data is in an R Time Series, you can analyze isolated time windows. Clipping the Time Series data Flashing back to our test case… Viewing the data as a time series is interesting. You can see that the work intensive time period is between 9:00 PM and 3:00 AM. Lets clip the data to the interesting period:     par(mfrow=c(2,1)) plot(g1gc.z$UserTime, type="h", main="User Time per GC\nTime: Complete Log File", xlab="Time of Day", ylab="CPU Seconds per GC", col="#1b9e77") clipped.g1gc.z=window(g1gc.z, start=as.POSIXct("2014-05-12 21:00:00"), end=as.POSIXct("2014-05-13 03:00:00")) plot(clipped.g1gc.z$UserTime, type="h", main="User Time per GC\nTime: Limited to Benchmark Execution", xlab="Time of Day", ylab="CPU Seconds per GC", col="#1b9e77") box(which = "outer", lty = "solid") Cumulative Incremental and Full GC count Here is the cumulative incremental and full GC count. When the line is very steep, it indicates that the GCs are repeating very quickly. Notice that the scale on the Y axis is different for full vs. incremental. plot(clipped.g1gc.z[,c(2:3)], main="Cumulative Incremental and Full GC count", xlab="Time of Day", col="#1b9e77") GC Analysis of Benchmark Execution using Time Series data In the following series of 3 graphs: The “After Size” show the amount of heap space in use after each garbage collection. Many Java objects are still referenced, i.e. alive, during each garbage collection. This may indicate that the application has a memory leak, or may indicate that the application has a very large memory footprint. Typically, an application's memory footprint plateau's in the early stage of execution. One would expect this graph to have a flat top. The steep decline in the heap space may indicate that the application crashed after 2:00. The second graph shows that the outliers in real execution time, discussed above, occur near 2:00. when the Java heap seems to be quite full. The third graph shows that Full GCs are infrequent during the first few hours of execution. The rate of Full GC's, (the slope of the cummulative Full GC line), changes near midnight.   plot(clipped.g1gc.z[,c("AfterSize","RealTime","FullCount")], xlab="Time of Day", col=c("#1b9e77","red","#1b9e77")) GC Analysis of heap recovered Each GC trace includes the amount of heap space in use before and after the individual GC event. During garbage coolection, unreferenced objects are identified, the space holding the unreferenced objects is freed, and thus, the difference in before and after usage indicates how much space has been freed. The following box plot and bar chart both demonstrate the same point - the amount of heap space freed per garbage colloection is surprisingly low. par(mfrow=c(2,1)) boxplot(as.vector(clipped.g1gc.z$Delta), main="Amount of Heap Recovered per GC Pass", xlab="Size in KB", horizontal = TRUE, col="red") hist(as.vector(clipped.g1gc.z$Delta), main="Amount of Heap Recovered per GC Pass", xlab="Size in KB", breaks=100, col="red") box(which = "outer", lty = "solid") This graph is the most interesting. The dark blue area shows how much heap is occupied by referenced Java objects. This represents memory that holds live data. The red fringe at the top shows how much data was recovered after each garbage collection. barplot(clipped.g1gc.z[,c("AfterSize","Delta")], col=c("#7570b3","#e7298a"), xlab="Time of Day", border=NA) legend("topleft", c("Live Objects","Heap Recovered on GC"), fill=c("#7570b3","#e7298a")) box(which = "outer", lty = "solid") When I discuss the data in the log files with the customer, I will ask for an explaination for the large amount of referenced data resident in the Java heap. There are two are posibilities: There is a memory leak and the amount of space required to hold referenced objects will continue to grow, limited only by the maximum heap size. After the maximum heap size is reached, the JVM will throw an “Out of Memory” exception every time that the application tries to allocate a new object. If this is the case, the aplication needs to be debugged to identify why old objects are referenced when they are no longer needed. The application has a legitimate requirement to keep a large amount of data in memory. The customer may want to further increase the maximum heap size. Another possible solution would be to partition the application across multiple cluster nodes, where each node has responsibility for managing a unique subset of the data. Conclusion In conclusion, R is a very powerful tool for the analysis of Java garbage collection log files. The primary difficulty is data cleansing so that information can be read into an R data frame. Once the data has been read into R, a rich set of tools may be used for thorough evaluation.

    Read the article

1