提交 0c1a0c12 authored 作者: Thomas Mueller's avatar Thomas Mueller

improve out of memory message

上级 1d514d5b
......@@ -9,6 +9,8 @@ package org.h2.compress;
import java.io.IOException;
import java.io.InputStream;
import org.h2.util.ByteUtils;
/**
* An input stream to read from an LZF stream.
* The data is automatically expanded.
......@@ -30,7 +32,7 @@ public class LZFInputStream extends InputStream {
}
private byte[] ensureSize(byte[] buff, int len) {
return buff == null || buff.length < len ? new byte[len] : buff;
return buff == null || buff.length < len ? ByteUtils.newBytes(len) : buff;
}
private void fillBuffer() throws IOException {
......
......@@ -40,6 +40,7 @@ import org.h2.table.TableFilter;
import org.h2.tools.CompressTool;
import org.h2.tools.Csv;
import org.h2.util.AutoCloseInputStream;
import org.h2.util.ByteUtils;
import org.h2.util.DateTimeUtils;
import org.h2.util.FileUtils;
import org.h2.util.MathUtils;
......@@ -1118,7 +1119,7 @@ public class Function extends Expression implements FunctionCall {
private byte[] getPaddedArrayCopy(byte[] data, int blockSize) {
int size = MathUtils.roundUp(data.length, blockSize);
byte[] newData = new byte[size];
byte[] newData = ByteUtils.newBytes(size);
System.arraycopy(data, 0, newData, 0, data.length);
return newData;
}
......
......@@ -21,6 +21,7 @@ import org.h2.store.DiskFile;
import org.h2.store.FileStore;
import org.h2.store.Record;
import org.h2.store.Storage;
import org.h2.util.ByteUtils;
import org.h2.util.FileUtils;
import org.h2.util.MathUtils;
import org.h2.util.ObjectArray;
......@@ -216,7 +217,7 @@ public class LogFile {
DataPage s = DataPage.create(database, buff);
int blocks = Math.abs(s.readInt());
if (blocks > 1) {
byte[] b2 = new byte[blocks * BLOCK_SIZE];
byte[] b2 = ByteUtils.newBytes(blocks * BLOCK_SIZE);
System.arraycopy(buff, 0, b2, 0, BLOCK_SIZE);
buff = b2;
file.readFully(buff, BLOCK_SIZE, blocks * BLOCK_SIZE - BLOCK_SIZE);
......@@ -306,7 +307,7 @@ public class LogFile {
break;
}
int sumLength = in.readInt();
byte[] summary = new byte[sumLength];
byte[] summary = ByteUtils.newBytes(sumLength);
if (sumLength > 0) {
in.read(summary, 0, sumLength);
}
......
......@@ -34,6 +34,7 @@ import org.h2.constant.SysProperties;
import org.h2.engine.ConnectionInfo;
import org.h2.jdbc.JdbcConnection;
import org.h2.message.Message;
import org.h2.util.ByteUtils;
import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.ObjectUtils;
......@@ -132,7 +133,7 @@ public class PgServerThread implements Runnable {
}
int len = dataInRaw.readInt();
len -= 4;
byte[] data = new byte[len];
byte[] data = ByteUtils.newBytes(len);
dataInRaw.readFully(data, 0, len);
dataIn = new DataInputStream(new ByteArrayInputStream(data, 0, len));
switch (x) {
......@@ -244,7 +245,7 @@ public class PgServerThread implements Runnable {
int paramCount = readShort();
for (int i = 0; i < paramCount; i++) {
int paramLen = readInt();
byte[] d2 = new byte[paramLen];
byte[] d2 = ByteUtils.newBytes(paramLen);
readFully(d2);
try {
setParameter(portal.prep, i, d2, formatCodes);
......
......@@ -62,6 +62,7 @@ import org.h2.tools.Restore;
import org.h2.tools.RunScript;
import org.h2.tools.Script;
import org.h2.tools.SimpleResultSet;
import org.h2.util.ByteUtils;
import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.MathUtils;
......@@ -402,7 +403,7 @@ class WebThread extends Thread implements DatabaseEventListener {
}
}
if (session != null && len > 0) {
byte[] bytes = new byte[len];
byte[] bytes = ByteUtils.newBytes(len);
for (int pos = 0; pos < len;) {
pos += input.read(bytes, pos, len - pos);
}
......
......@@ -15,6 +15,7 @@ import java.sql.Timestamp;
import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.message.Message;
import org.h2.util.ByteUtils;
import org.h2.util.MathUtils;
import org.h2.value.Value;
import org.h2.value.ValueArray;
......@@ -200,7 +201,7 @@ public abstract class DataPage {
*/
public void checkCapacity(int plus) {
if (pos + plus >= data.length) {
byte[] d = new byte[(data.length + plus) * 2];
byte[] d = ByteUtils.newBytes((data.length + plus) * 2);
// must copy everything, because pos could be 0 and data may be
// still required
System.arraycopy(data, 0, d, 0, data.length);
......@@ -545,13 +546,13 @@ public abstract class DataPage {
}
case Value.JAVA_OBJECT: {
int len = readInt();
byte[] b = createByteArray(len);
byte[] b = ByteUtils.newBytes(len);
read(b, 0, len);
return ValueJavaObject.getNoCopy(b);
}
case Value.BYTES: {
int len = readInt();
byte[] b = createByteArray(len);
byte[] b = ByteUtils.newBytes(len);
read(b, 0, len);
return ValueBytes.getNoCopy(b);
}
......@@ -571,7 +572,7 @@ public abstract class DataPage {
case Value.CLOB: {
int smallLen = readInt();
if (smallLen >= 0) {
byte[] small = createByteArray(smallLen);
byte[] small = ByteUtils.newBytes(smallLen);
read(small, 0, smallLen);
return ValueLob.createSmallLob(dataType, small);
}
......@@ -605,16 +606,6 @@ public abstract class DataPage {
}
}
private byte[] createByteArray(int len) {
try {
return new byte[len];
} catch (OutOfMemoryError e) {
Error e2 = new OutOfMemoryError("Requested memory: " + len);
e2.initCause(e);
throw e2;
}
}
/**
* Fill up the buffer with empty space and an (initially empty) checksum
* until the size is a multiple of Constants.FILE_BLOCK_SIZE.
......
......@@ -28,6 +28,7 @@ import org.h2.log.RedoLogRecord;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.util.BitField;
import org.h2.util.ByteUtils;
import org.h2.util.Cache;
import org.h2.util.Cache2Q;
import org.h2.util.CacheLRU;
......@@ -584,7 +585,7 @@ public class DiskFile implements CacheWriter {
throw Message.getInternalError("0 blocks to read pos=" + pos);
}
if (blockCount > 1) {
byte[] b2 = new byte[blockCount * BLOCK_SIZE];
byte[] b2 = ByteUtils.newBytes(blockCount * BLOCK_SIZE);
System.arraycopy(buff, 0, b2, 0, BLOCK_SIZE);
buff = b2;
file.readFully(buff, BLOCK_SIZE, blockCount * BLOCK_SIZE - BLOCK_SIZE);
......
......@@ -14,6 +14,7 @@ import org.h2.constant.SysProperties;
import org.h2.engine.Constants;
import org.h2.message.Message;
import org.h2.tools.CompressTool;
import org.h2.util.ByteUtils;
/**
* An input stream that is backed by a file store.
......@@ -119,7 +120,7 @@ public class FileStoreInputStream extends InputStream {
page.readInt();
if (compress != null) {
int uncompressed = page.readInt();
byte[] buff = new byte[remainingInBuffer];
byte[] buff = ByteUtils.newBytes(remainingInBuffer);
page.read(buff, 0, remainingInBuffer);
page.reset();
page.checkCapacity(uncompressed);
......
......@@ -9,6 +9,8 @@ package org.h2.store.fs;
import java.io.EOFException;
import java.io.IOException;
import org.h2.util.ByteUtils;
/**
* In this file system, files are kept fully in memory until stored.
*/
......@@ -55,7 +57,7 @@ public class FileObjectDatabase implements FileObject {
public void setFileLength(long newLength) {
this.length = (int) newLength;
if (length != data.length) {
byte[] n = new byte[length];
byte[] n = ByteUtils.newBytes(length);
System.arraycopy(data, 0, n, 0, Math.min(data.length, n.length));
data = n;
changed = true;
......@@ -73,7 +75,7 @@ public class FileObjectDatabase implements FileObject {
public void write(byte[] b, int off, int len) {
if (pos + len > data.length) {
int newLen = Math.max(data.length * 2, pos + len);
byte[] n = new byte[newLen];
byte[] n = ByteUtils.newBytes(newLen);
System.arraycopy(data, 0, n, 0, length);
data = n;
}
......
......@@ -26,6 +26,7 @@ import org.h2.compress.LZFInputStream;
import org.h2.compress.LZFOutputStream;
import org.h2.constant.ErrorCode;
import org.h2.message.Message;
import org.h2.util.ByteUtils;
import org.h2.util.StringUtils;
/**
......@@ -43,10 +44,10 @@ public class CompressTool {
private static byte[] getBuffer(int min) {
if (min > MAX_BUFFER_SIZE) {
return new byte[min];
return ByteUtils.newBytes(min);
}
if (buffer == null || buffer.length < min) {
buffer = new byte[min];
buffer = ByteUtils.newBytes(min);
}
return buffer;
}
......@@ -77,7 +78,7 @@ public class CompressTool {
Compressor compress = getCompressor(algorithm);
byte[] buff = getBuffer((len < 100 ? len + 100 : len) * 2);
int newLen = compress(in, in.length, compress, buff);
byte[] out = new byte[newLen];
byte[] out = ByteUtils.newBytes(newLen);
System.arraycopy(buff, 0, out, 0, newLen);
return out;
}
......@@ -111,7 +112,7 @@ public class CompressTool {
try {
int len = readInt(in, 1);
int start = 1 + getLength(len);
byte[] buff = new byte[len];
byte[] buff = ByteUtils.newBytes(len);
compress.expand(in, start, in.length - start, buff, 0, len);
return buff;
} catch (Exception e) {
......
......@@ -490,7 +490,7 @@ public class Recover extends Tool implements DataHandler {
s = DataPage.create(this, buff);
blocks = Math.abs(s.readInt());
if (blocks > 1) {
byte[] b2 = new byte[blocks * blockSize];
byte[] b2 = ByteUtils.newBytes(blocks * blockSize);
System.arraycopy(buff, 0, b2, 0, blockSize);
buff = b2;
try {
......@@ -525,7 +525,7 @@ public class Recover extends Tool implements DataHandler {
case 'S': {
char fileType = (char) s.readByte();
int sumLength = s.readInt();
byte[] summary = new byte[sumLength];
byte[] summary = ByteUtils.newBytes(sumLength);
if (sumLength > 0) {
s.read(summary, 0, sumLength);
}
......
......@@ -236,6 +236,25 @@ public class ByteUtils {
byte[] copy = new byte[len];
System.arraycopy(b, 0, copy, 0, len);
return copy;
}
/**
* Create an array of bytes with the given size. If this is not possible
* because not enough memory is available, an OutOfMemoryError with the
* requested size in the message is thrown.
*
* @param len the number of bytes requested
* @return the byte array
* @throws OutOfMemoryError
*/
public static byte[] newBytes(int len) {
try {
return new byte[len];
} catch (OutOfMemoryError e) {
Error e2 = new OutOfMemoryError("Requested memory: " + len);
e2.initCause(e);
throw e2;
}
}
}
......@@ -33,6 +33,7 @@ import org.h2.engine.SessionInterface;
import org.h2.message.Message;
import org.h2.message.TraceSystem;
import org.h2.tools.SimpleResultSet;
import org.h2.util.ByteUtils;
import org.h2.util.ExactUTF8InputStreamReader;
import org.h2.util.IOUtils;
import org.h2.util.NetUtils;
......@@ -273,7 +274,7 @@ public class Transfer {
if (len == -1) {
return null;
}
byte[] b = new byte[len];
byte[] b = ByteUtils.newBytes(len);
in.readFully(b);
return b;
}
......
......@@ -342,10 +342,10 @@ public class ValueLob extends Value {
remaining = length;
}
int len = getBufferSize(handler, compress, remaining);
byte[] buff = new byte[len];
byte[] buff = ByteUtils.newBytes(len);
len = IOUtils.readFully(in, buff, 0, len);
if (len <= handler.getMaxLengthInplaceLob()) {
byte[] small = new byte[len];
byte[] small = ByteUtils.newBytes(len);
System.arraycopy(buff, 0, small, 0, len);
return ValueLob.createSmallLob(Value.BLOB, small);
}
......@@ -693,7 +693,7 @@ public class ValueLob extends Value {
int len = getBufferSize(handler, compress, Long.MAX_VALUE);
int tabId = tableId;
if (type == Value.BLOB) {
createFromStream(new byte[len], 0, getInputStream(), Long.MAX_VALUE, handler);
createFromStream(ByteUtils.newBytes(len), 0, getInputStream(), Long.MAX_VALUE, handler);
} else {
createFromReader(new char[len], 0, getReader(), Long.MAX_VALUE, handler);
}
......
......@@ -266,8 +266,6 @@ java org.h2.test.TestAll timer
/*
move DataPage.createByteArray to ByteUtils, improve message
run the performance tests as part of the unit test
switch to JDK 1.6 by default
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论