After upgrading to the latest JDK, we've got (on some machines) a strange OutOfMemoryException.
Consider this simple application:
public class Test
{
public static void main (String[] args) {
try {
java.text.SimpleDateFormat dateFormatter = new java.text.SimpleDateFormat("E dd/MM/yyyy HH:mm");
System.out.println("formatted date: " + dateFormatter.format(new java.util.Date()));
} catch (Exception x) {
System.err.println(x);
System.exit(1);
}
}
}
Running this small program will result in this exception (even when running it with -Xmx2048M -Xms2048):
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Currency.readLongArray(Currency.java:657)
at java.util.Currency.access$100(Currency.java:76)
at java.util.Currency$1.run(Currency.java:211)
at java.security.AccessController.doPrivileged(Native Method)
at java.util.Currency.<clinit>(Currency.java:192)
at java.text.DecimalFormatSymbols.initialize(DecimalFormatSymbols.java:566)
at java.text.DecimalFormatSymbols.<init>(DecimalFormatSymbols.java:94)
at java.text.DecimalFormatSymbols.getInstance(DecimalFormatSymbols.java:157)
at java.text.NumberFormat.getInstance(NumberFormat.java:767)
at java.text.NumberFormat.getIntegerInstance(NumberFormat.java:439)
at java.text.SimpleDateFormat.initialize(SimpleDateFormat.java:664)
at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:585)
at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:560)
at Test.main(Test.java:5)
Could someone please explain this to me?
The java version we are using is:
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
When we are using a prior version, we have no problem:
java -version
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b16)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)
java Test
formatted date: ma 21/10/2013 10:19
Update: Before everyone is mentioning increasing the heap size... I already tried it:
java -Xmx2048M -Xms2048M Test
Runtime.getRuntime().freeMemory(): 2048120480
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Currency.readLongArray(Currency.java:657)
at java.util.Currency.access$100(Currency.java:76)
at java.util.Currency$1.run(Currency.java:211)
at java.security.AccessController.doPrivileged(Native Method)
at java.util.Currency.<clinit>(Currency.java:192)
at java.text.DecimalFormatSymbols.initialize(DecimalFormatSymbols.java:566)
at java.text.DecimalFormatSymbols.<init>(DecimalFormatSymbols.java:94)
at java.text.DecimalFormatSymbols.getInstance(DecimalFormatSymbols.java:157)
at java.text.NumberFormat.getInstance(NumberFormat.java:767)
at java.text.NumberFormat.getIntegerInstance(NumberFormat.java:439)
at java.text.SimpleDateFormat.initialize(SimpleDateFormat.java:664)
at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:585)
at java.text.SimpleDateFormat.<init>(SimpleDateFormat.java:560)
at Test.main(Test.java:8)
I dug into the code of java.util.Currency. It reads in a resource file located in the Java JRE, in the static Class initializer block.
String homeDir = System.getProperty("java.home");
try {
String dataFile = homeDir + File.separator +
"lib" + File.separator + "currency.data";
DataInputStream dis = new DataInputStream(
new BufferedInputStream(
new FileInputStream(dataFile)));
if (dis.readInt() != MAGIC_NUMBER) {
throw new InternalError("Currency data is possibly corrupted");
}
formatVersion = dis.readInt();
if (formatVersion != VALID_FORMAT_VERSION) {
throw new InternalError("Currency data format is incorrect");
}
dataVersion = dis.readInt();
mainTable = readIntArray(dis, A_TO_Z * A_TO_Z);
int scCount = dis.readInt();
scCutOverTimes = readLongArray(dis, scCount);
As you can see, it reads in JRE/lib/currency.data. The fourth integer contains the scCount. This integer will be too high. I guess that that file is corrupt. Try replacing it.
Related
I have this code:
public class CalculatingApp {
public static void main(String[] args) {
AtomicInteger result = new AtomicInteger();
int valueA = Integer.parseInt(args[0]);
String operation = args[1];
int valueB = Integer.parseInt(args[2]);
if ("add".equals(operation)) {
result.set(valueA + valueB);
} else if ("subt".equals(operation)) {
result.set(valueA - valueB);
} else if ("mult".equals(operation)) {
result.set(valueA * valueB);
} else if ("div".equals(operation)) {
result.set(valueA / valueB);
} else {
System.out.println("Incorrect input");
}
System.out.println(result.get());
}
}
I use IDEa terminal for these commands:
javac CalculatingApp.java
java CalculatingApp 5 add 10
But console output:
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.UnsupportedClassVersionError: CalculatingApp has been compiled by a more recent version of the Java Runtime (class file version 57.0), this version
of the Java Runtime only recognizes class file versions up to 52.0
Java -version:
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)
You may find other errors.
Looks the code is compiled by JAVA8, but ran by Java 13.
Try java -version in IDEA terminal to take a look the java version.
We are using Tess4J/Tesseract to perform OCR on a webapp. On Windows everything works fine but when deployed on a Linux machine(CentOS 6.8) the program crashes and automatically kill the Apache tomcat server.
We are read more than one file(different file) simultaneously.if we run the OCR it running approximately 1 minutes after it through fatal error. Can you please suggest how to resolve?
A fatal error has been detected by the Java Runtime Environment:
SIGSEGV (0xb) at pc=0x00007f7d5934ff90, pid=17649,
tid=140176377489152
JRE version: Java(TM) SE Runtime Environment (8.0_60-b27) (build 1.8.0_60-b27)
Java VM: Java HotSpot(TM) 64-Bit Server VM (25.60-b23 mixed mode linux-amd64 compressed oops)
Problematic frame:
C [libtesseract.so.3.0.2+0x22cf90] tesseract::HistogramRect(unsigned char const*, int, int, int, int, int, int, int*)+0x70
Failed to write core dump. Core dumps have been disabled. To enable core dumping, try ulimit -c unlimited before starting Java again
I fixed it by resizing the image to a fixed size (you could do a percentage resize I guess) in javacv before passing it to tess4j.
Example of my resize method.
public static IplImage resize(IplImage img_source){
IplImage resized = IplImage.create(600, 480, img_source.depth(), img_source.nChannels());
cvResize(img_source,resized);
return resized;
}
Then I do my tesseract extraction below:
public static String extract(BufferedImage bi, Rectangle r) throws CvHandler, IOException, TesseractException{
ITesseract tess = new Tesseract();
String tessPath = getTess();
tess.setPageSegMode(1);
tess.setLanguage("eng");
tess.setDatapath(tessPath);
tess.setOcrEngineMode(TessOcrEngineMode.OEM_DEFAULT);
tess.setTessVariable("load_system_dawg", "false");
tess.setTessVariable("load_freq_dawg", "false");
tess.setTessVariable("tessedit_create_hocr", "0");
tess.setTessVariable("tessedit_char_whitelist","ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
String result = "";
if (!r.getBounds().isEmpty()){
try{
result = tess.doOCR(bi, r);
}catch(TesseractException e){
throw new CvHandler(e.getMessage());
}
}else result = tess.doOCR(bi);
return result;
}
Helper method for converting IplImage to BufferedImage Source:
public static BufferedImage convertIplToBuffered(IplImage img){
OpenCVFrameConverter.ToIplImage grabberConverter = new OpenCVFrameConverter.ToIplImage();
Java2DFrameConverter paintConverter = new Java2DFrameConverter();
Frame frame = grabberConverter.convert(img);
BufferedImage img_result = paintConverter.getBufferedImage(frame,1);
return img_result;
}
For a project for school I have to work with multiple phidgets. I created a class that opens a manager, scan's for connected phidgets and initializes their listeners depending on the kind of phidget. One of the phidgets is a RFID scanner. Now to test this phidget I made this initializer method (shortened code as a couple of extra listeners are created, but the don't create an error)
public void initRFIDPhidget(RFIDPhidget rfid, int serialNumber){
try {
rfid.open(serialNumber);
rfid.waitForAttachment();
rfid.setAntennaOn(true);
rfid.setLEDOn(false);
} catch (PhidgetException ex) {
Logger.getLogger(PhidgetMain.class.getName()).log(Level.SEVERE, null, ex);
}
rfid.addTagGainListener(new TagGainListener(){
public void tagGained(TagGainEvent tge) {
try {
System.out.println(Boolean.toString(rfid.getTagStatus()));
if(rfid.getTagStatus())
System.out.println((rfid.getLastTag())); // <--- This line
rfid.setLEDOn(true);
} catch (PhidgetException ex) {
Logger.getLogger(PhidgetMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
The as you can see there is one line that gives me a bit of a problem. Whenever I ask for the getLastTag() method it gives me a huge runtime error. Weird thing is, this only happens when I start my program with my tag away from the phidget. If my tag lies on the RFID scanner when I initialize it, it runs perfectly.
Do you guys have any ideas why it works like that?
edit: as was asked I'm adding the rest of the code and the full error message
//test variable
public static final String TEST_TAG_ID = "1e00acf9d4";
//used variables
private Manager phidgetMgr;
private Vector phidgetVec;
public static void main(String[] args){
new PhidgetMain();
//Initialize other programs in different threads here
}
public PhidgetMain(){
try {
phidgetMgr = new Manager();
phidgetMgr.open();
System.out.println("MANAGER OPENED\nWAITING FOR PHIDGETS TO CONNECT...");
//Give phidgets time to connect
Thread.sleep(1000);
//Iterate through phidgets and initialize them
System.out.println("OPENING PHIDGETS");
phidgetVec = phidgetMgr.getPhidgets();
for(int i = 0; i<phidgetVec.size(); i++){
System.out.println("OPENING PHIDGET NUMBER " + (i+1));
System.out.println("PHIDGET ID CODE: "+((Phidget)phidgetVec.get(i)).getDeviceID()); //Number identical for the type of phidget
System.out.println("PHIDGET SERIAL NUMBER: "+((Phidget)phidgetVec.get(i)).getSerialNumber());
try{
if(((Phidget)phidgetVec.get(i)).getDeviceID()==Phidget.PHIDID_RFID_2OUTPUT){
RFIDPhidget rfid = new RFIDPhidget();
initRFIDPhidget(rfid,((Phidget)phidgetVec.get(i)).getSerialNumber());
} else if(((Phidget)phidgetVec.get(i)).getDeviceID()==Phidget.PHIDID_INTERFACEKIT_8_8_8/*CONSTANTE KAN NIET KLOPPEN ZOEK DE OUTPUT TUSSEN DE CONSTANTEN IN DEZE LINK: http://www.phidgets.com/documentation/web/javadoc/ */){
InterfaceKitPhidget ikp = new InterfaceKitPhidget();
initInterfaceKitPhidget(ikp,((Phidget)phidgetVec.get(i)).getSerialNumber());
}
} catch(PhidgetException ex){
System.out.println("OPENING PHIDGET NUMBER " + (i+1) + " THREW AN EXCEPTION");
}
}
} catch (PhidgetException | InterruptedException ex) {
Logger.getLogger(PhidgetMain.class.getName()).log(Level.SEVERE, null, ex);
}
}
This is the full output:
WAITING FOR PHIDGETS TO CONNECT...
OPENING PHIDGETS
OPENING PHIDGET NUMBER 1
PHIDGET ID CODE: 49
PHIDGET SERIAL NUMBER: 88983
RFID SCANNER OPENED
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000050fc9890, pid=12772, tid=17936
#
# JRE version: Java(TM) SE Runtime Environment (8.0_73-b02) (build 1.8.0_73-b02)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.73-b02 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# V [jvm.dll+0x279890]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\Users\Typhaon\Documents\NetBeansProjects\FYS\hs_err_pid12772.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
#
C:\Users\Typhaon\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 4 seconds)
I´m want to replace a String expression and I receive this error message
error: cannot find symbol
test1 = testw.replaceAll("/uploads","http://www.anbariloche.com.ar/uploads");
symbol: method replaceAll(String,String)
location: variable testw of type String
this is my code
String testw= String.valueOf(element1);
String test1;
test1 = testw.replaceAll("/uploads","http://www.anbariloche.com.ar/uploads");
I use Netbeans 8.1
Product Version: NetBeans IDE 8.1 (Build 201510222201)
Java: 1.7.0_79; Java HotSpot(TM) Client VM 24.79-b02
Runtime: Java(TM) SE Runtime Environment 1.7.0_79-b15
System: Windows 7 version 6.1 running on x86; Cp1252; es_ES (nb)
The complete code updated
#Override
protected void beforePortada(Form f) {
WebBrowser browser=new WebBrowser();
f.setLayout(new BorderLayout());
f.addComponent(BorderLayout.CENTER, browser);
/////Parse
String URL= "http://www.anbariloche.com.ar/";
ConnectionRequest req = new ConnectionRequest();
req.setUrl(URL);
NetworkManager.getInstance().addToQueueAndWait(req);
byte[] data = req.getResponseData();
if (data == null) {
}
XMLParser xmlParser=new XMLParser();
Element element= null;
try {
element = xmlParser.parse(new InputStreamReader(new ByteArrayInputStream(data), "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Element element1=element.getChildAt(0);
String testw= String.valueOf(element1);
///replace the string
testw = testw.replaceAll("/uploads/","http://www.anbariloche.com.ar/uploads/");
browser.setPage(testw,null);
}
}
That's the code updated, I can see where is my mistake
with the String
Use StringUtil.replaceAll(string, pattern, replace).
Implementing this in the VM layer is much harder to do in a truly portable way and so we nudge you towards the more portable versions.
There will not be any error in netbean while coding and it shows runtime error so StringUtil should be imported and called its replaceAll static method
eg: StringUtil.replaceAll
I have following piece of test code:
try {
InputStream is;
Stopwatch.start("FileInputStream");
is = new FileInputStream(imageFile.toFile());
is.skip(1024*1024*1024);
is.close();
Stopwatch.stop();
Stopwatch.start("Files.newInputStream");
is = Files.newInputStream(imageFile);
is.skip(1024*1024*1024);
is.close();
Stopwatch.stop();
}
catch(Exception e)
{
}
and I have following output:
Start: FileInputStream
FileInputStream : 0 ms
Start: Files.newInputStream
Files.newInputStream : 3469 ms
Do you have any idea what is going on? Why skip is so slow in the second case?
I need to use InputStreams acquired from channels because my test have shown that best for my task is to have two threads reading from file simultaneously (and I can notice any improvement only when I am using Streams from Channels).
During tests I figured out that I can do something like this:
SeekableByteChannel sbc = Files.newByteChannel(imageFile);
sbc.position(1024*1024*1024);
is = Channels.newInputStream(sbc);
which takes only avg. 28ms but that does not help me a lot because to use that I would have to make major API changes.
My platform:
Linux galileo 3.11.0-13-generic #20-Ubuntu SMP Wed Oct 23 07:38:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
Looking at the source, it appears that the default implementation of skip() is actually reading through (and discarding) the stream content until it reaches the target position:
public long skip(long n) throws IOException {
long remaining = n;
int nr;
if (n <= 0) {
return 0;
}
int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
byte[] skipBuffer = new byte[size];
while (remaining > 0) {
nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
if (nr < 0) {
break;
}
remaining -= nr;
}
return n - remaining;
}
The SeekableByteChannel#position() method probably just updates an offset pointer, which doesn't actually require any I/O. Presumably, FileInputStream overrides the skip() method with a similar optimization. The documentation supports this theory:
This method may skip more bytes than are remaining in the backing file. This produces no exception and the number of bytes skipped may include some number of bytes that were beyond the EOF of the backing file. Attempting to read from the stream after skipping past the end will result in -1 indicating the end of the file.
On platter disks or network storage, this could have a significant impact.
Try to set the range with GetObjectRequest.setRange to have the same behavior of skip.
GetObjectRequest req = new GetObjectRequest(BUCKET_NAME, "myfile.zip");
req.setRange(1024); // start download skiping 1024 bytes
S3ObjectInputStream in = client.getObject(req).getObjectContent();
// read "in" while not eof
I used this to avoid SocketTimeoutException on my implementation.
Each time I got a SocketTimeoutException I restart the download using the setRange to skip the bytes that I already downloaded.