Basically, it is necessary to investigate and analyze with gcviewer-1.36 or Memory Analyzer to identify the cause. In my case, I need to save a large object every second, and I get an error in less than an hour.
Countermeasure:
startup_parameters.sh
appserver_mem="6000m"
appserver_java_opt="-Xms=3074m -Xmx=3074m -XX:PermSize=1024m -XX:MaxPermSize=1024m -XX:NewSize=1024m -XX:MaxNewSize=1024m -server -Djava.awt.headless=true"
flyweight core class
FlyweightPool.java
package util;
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
public class FlyweightPool<T> {
private WeakHashMap<T, WeakReference<T>> pool = new WeakHashMap<>();
public FlyweightPool() {}
public T flyweightOf(T obj) {
if (obj == null) {
return null;
}
synchronized(pool) {
WeakReference<T> w = pool.get(obj);
T flyweihgt = (w == null ? null : w.get());
if (flyweihgt != null) {
return flyweihgt;
}
pool.put(obj, new WeakReference<T>(obj));
return obj;
}
}
public boolean contains(T obj) {
synchronized (pool) {
return pool.containsKey(obj);
}
}
public void remove(T obj) {
synchronized (pool) {
pool.remove(obj);
}
}
}
flyweight implementation class
TsunamiBinaryPointBean.java
private static final FlyweightPool<List<TsunamiBinaryFauldBean>> listFlyweights = new FlyweightPool<>();
private static final FlyweightPool<TsunamiBinaryFauldBean> dataFlyweight = new FlyweightPool<>();
/**
*Set the point ID
*/
public void setPointID(String pointID){
this.pointID = StringUtil.flyweightOf(pointID);
}
/**
*Memory tuning, flyweight objects
*/
public void optimizeMemory() {
List<TsunamiBinaryFauldBean> fauldBean;
synchronized(this.tsunamiBinaryFaulds) {
TsunamiBinaryFauldBean[] dataArr = new TsunamiBinaryFauldBean[this.tsunamiBinaryFaulds.size()];
for (int i = 0; i < this.tsunamiBinaryFaulds.size(); i++) {
dataArr[i] = dataFlyweight.flyweightOf(this.tsunamiBinaryFaulds.get(i));
}
fauldBean = listFlyweights.flyweightOf(Arrays.asList(dataArr));
}
this.tsunamiBinaryFaulds = fauldBean;
}
compression
XXX.java
public static ByteBuffer compress(ByteBuffer buffer){
ByteArrayOutputStream compressBaos = new ByteArrayOutputStream();
GZIPOutputStream gzip = null;
try{
gzip = new GZIPOutputStream(compressBaos) {{
def.setLevel(Deflater.BEST_COMPRESSION);
}};
gzip.write(buffer.array());
gzip.finish();
gzip.flush();
compressBaos.flush();
byte[] compressed = compressBaos.toByteArray();
return ByteBuffer.wrap(compressed);
}catch(IOException e){
DonetLogger.LOGGER.error(1,"ByteBuffer compression", "An error has occurred.", e);
return null;
}finally{
try{
if(gzip != null){
gzip.close();
}
}catch(Exception e){}
try{
if(compressBaos != null){
compressBaos.close();
}
}catch(Exception e){}
gzip = null;
compressBaos = null;
}
}
Defrost
XXX.java
public static ByteBuffer decompress(ByteBuffer buffer){
ByteArrayOutputStream decompressBaos = new ByteArrayOutputStream();
GZIPInputStream gzip = null;
byte[] b = new byte[1024*100];
try{
gzip = new GZIPInputStream(new ByteArrayInputStream(buffer.array()));
for (int read = gzip.read(b); read >= 0; read = gzip.read(b)) {
decompressBaos.write(b, 0, read);
}
decompressBaos.flush();
byte[] decompressed = decompressBaos.toByteArray();
return ByteBuffer.wrap(decompressed);
}catch(IOException e){
DonetLogger.LOGGER.error(1,"ByteBuffer decompression", "An error has occurred. Check the accuracy of ByteBuffer.", e);
return null;
}finally{
try{
if(gzip != null){
gzip.close();
}
}catch(Exception e){}
try{
if(decompressBaos != null){
decompressBaos.close();
}
}catch(Exception e){}
gzip = null;
decompressBaos = null;
}
}
Binary output
XXX.java
public void binaryWrite(DataOutputStream output) throws IOException{
if(this.getPointCount() <= 0){
return;
}
output.writeUTF(this.header);
output.writeUTF(toSimpleDateTimeString(this.tsunamiDatetime));
output.writeShort(pointCount);
for(TsunamiBinaryPointBean point :tsunamiBinaryPoints){
output.writeUTF(point.getAreaID());
output.writeUTF(point.getPointID());
output.writeFloat(point.getLineAbsAverage());
output.writeShort(point.getFauldCount());
output.writeFloat(point.getFirstLineAbsAverage());
for(int i=0; i<point.getTsunamiBinaryFaulds().length; i++){
output.writeUTF(point.getTsunamiBinaryFaulds()[i].getFauldID());
output.writeUTF(point.getTsunamiBinaryFaulds()[i].getStartDatetime());
output.writeFloat(point.getTsunamiBinaryFaulds()[i].getAmplificationFactor());
output.writeFloat(point.getTsunamiBinaryFaulds()[i].getFauldAbsAverageValue());
}
}
output.flush();
}
Binary reception What is output by DataOutputStream is only received by DataInputStream, and in other cases it becomes an unintended operation.
XXX.java
public static ByteBuffer toByteBuffer(DataInputStream input){
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(buffer);
byte[] result;
try{
out.writeUTF(input.readUTF());
out.writeUTF(input.readUTF());
int point = input.readShort();
out.writeShort(point);
for(int i=0;i<point;i++){
out.writeUTF(input.readUTF());
out.writeUTF(input.readUTF());
out.writeFloat(input.readFloat());
int fauld = input.readShort();
out.writeShort(fauld);
out.writeFloat(input.readFloat());
for(int j=0;j<fauld;j++){
out.writeUTF(input.readUTF());
out.writeUTF(input.readUTF());
out.writeFloat(input.readFloat());
out.writeFloat(input.readFloat());
}
}
result = buffer.toByteArray();
return ByteBuffer.wrap(result);
}catch(IOException e){
return null;
}finally{
try {
if (out != null) {
out.close();
}
}catch (IOException e) {}
try {
if (buffer != null) {
buffer.close();
}
}catch (IOException e) {}
buffer = null;
out = null;
}
}
Recommended Posts