I am using 4019th build. I added -Xmx1500M and it is still not enough. I have a theory that the coverage data files are broken - there were several processes exitting at the same time. Is there anything I can do to avoid this problem?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I suspect you are correct. I have seen this on pre-4019 builds and it is caused by concurrent writes to the same *.ec file (the out-of-mem error is caused by a piece of data that can't be de-serialized). The *.em and *.ec file format is made semi-transactional to help prevent this but it doesn't prevent corruption when the writes are made from independent processes.
There are actually two variations of this problem:
(a) in a scenario when people do not install emma.jar as a JRE extension it is possible that EMMA's runtime will be loaded by multiple classloaders (can happen in ANT/JUnit etc). In this case there will also be multiple exit hooks registered and they will all run concurrently on VM exit. In build 4019 I've made coverage data dumping into a VM-global critical section to avoid file corruption.
(This is also avoided if EMMA is a JRE extension, because its runtime is singly-loaded then)
(b) the above does not apply when you have truly multiple *OS processes* writing to the same dump file. I have plans to leverage file locking to avoid corruption here, but it is J2SE 1.4+ only and is somewhat platform-specific. Short of using my own lock files, I have no good ideas (yet) on making sure concurrent file dumps are guaranteed to be safe.
However, there are ways to avoid this problem:
- can you make you sure your process exits are staggered in time?
- if not, can you tell different processes to use *different* dump files (-Demma.coverage.out.file=<different file each time> or different emma.properties classpath resources) to begin with? It may or may not be convenient depending on how you start the processes.
I will add this as a high priority bug to the tracker. It would help me if you add data on the exact Java and OS versions you are using.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you. Unfortunately I cannot easily modify server startup. As a work-around can you provide an option to always create a new file (in format name.number.ext)? I will merge all the files before reporting.
I remember from my Perl days we used to use directory creation for locking - only one process can create a directory and other processes will have to wait. Unfortunately if one of the processes dies others can wait forever, but I think there could be a timeout for that situation.
- Alexey.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am using 4019th build. I added -Xmx1500M and it is still not enough. I have a theory that the coverage data files are broken - there were several processes exitting at the same time. Is there anything I can do to avoid this problem?
Alexey,
I suspect you are correct. I have seen this on pre-4019 builds and it is caused by concurrent writes to the same *.ec file (the out-of-mem error is caused by a piece of data that can't be de-serialized). The *.em and *.ec file format is made semi-transactional to help prevent this but it doesn't prevent corruption when the writes are made from independent processes.
There are actually two variations of this problem:
(a) in a scenario when people do not install emma.jar as a JRE extension it is possible that EMMA's runtime will be loaded by multiple classloaders (can happen in ANT/JUnit etc). In this case there will also be multiple exit hooks registered and they will all run concurrently on VM exit. In build 4019 I've made coverage data dumping into a VM-global critical section to avoid file corruption.
(This is also avoided if EMMA is a JRE extension, because its runtime is singly-loaded then)
(b) the above does not apply when you have truly multiple *OS processes* writing to the same dump file. I have plans to leverage file locking to avoid corruption here, but it is J2SE 1.4+ only and is somewhat platform-specific. Short of using my own lock files, I have no good ideas (yet) on making sure concurrent file dumps are guaranteed to be safe.
However, there are ways to avoid this problem:
- can you make you sure your process exits are staggered in time?
- if not, can you tell different processes to use *different* dump files (-Demma.coverage.out.file=<different file each time> or different emma.properties classpath resources) to begin with? It may or may not be convenient depending on how you start the processes.
I will add this as a high priority bug to the tracker. It would help me if you add data on the exact Java and OS versions you are using.
Thank you. Unfortunately I cannot easily modify server startup. As a work-around can you provide an option to always create a new file (in format name.number.ext)? I will merge all the files before reporting.
I remember from my Perl days we used to use directory creation for locking - only one process can create a directory and other processes will have to wait. Unfortunately if one of the processes dies others can wait forever, but I think there could be a timeout for that situation.
- Alexey.
Archived as a new feature request: http://sourceforge.net/tracker/index.php?func=detail&aid=974340&group_id=108932&atid=651900