All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.parquet.hadoop.codec.CleanUtil Maven / Gradle / Ivy

There is a newer version: 1.14.4
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.parquet.hadoop.codec;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A Helper class which use reflections to clean up DirectBuffer. It's implemented for
 * better compatibility with both java8 and java9+, because the Cleaner class is moved to
 * another place since java9+.
 * 

* Strongly inspired by: * https://github.com/apache/tomcat/blob/master/java/org/apache/tomcat/util/buf/ByteBufferUtils.java */ public class CleanUtil { private static final Logger logger = LoggerFactory.getLogger(CleanUtil.class); private static final Object unsafe; private static final Method cleanerMethod; private static final Method cleanMethod; private static final Method invokeCleanerMethod; private static final int majorVersion = Integer.parseInt(System.getProperty("java.version").split("\\D+")[0]); static { final ByteBuffer tempBuffer = ByteBuffer.allocateDirect(0); Method cleanerMethodLocal = null; Method cleanMethodLocal = null; Object unsafeLocal = null; Method invokeCleanerMethodLocal = null; if (majorVersion >= 9) { try { final Class clazz = Class.forName("sun.misc.Unsafe"); final Field theUnsafe = clazz.getDeclaredField("theUnsafe"); theUnsafe.setAccessible(true); unsafeLocal = theUnsafe.get(null); invokeCleanerMethodLocal = clazz.getMethod("invokeCleaner", ByteBuffer.class); invokeCleanerMethodLocal.invoke(unsafeLocal, tempBuffer); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | ClassNotFoundException | NoSuchFieldException e) { logger.warn("Cannot use direct ByteBuffer cleaner, memory leaking may occur", e); unsafeLocal = null; invokeCleanerMethodLocal = null; } } else { try { cleanerMethodLocal = tempBuffer.getClass().getMethod("cleaner"); cleanerMethodLocal.setAccessible(true); final Object cleanerObject = cleanerMethodLocal.invoke(tempBuffer); cleanMethodLocal = cleanerObject.getClass().getMethod("clean"); cleanMethodLocal.invoke(cleanerObject); } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { logger.warn("Cannot use direct ByteBuffer cleaner, memory leaking may occur", e); cleanerMethodLocal = null; cleanMethodLocal = null; } } cleanerMethod = cleanerMethodLocal; cleanMethod = cleanMethodLocal; unsafe = unsafeLocal; invokeCleanerMethod = invokeCleanerMethodLocal; } private CleanUtil() { // Hide the default constructor since this is a utility class. } public static void cleanDirectBuffer(ByteBuffer buf) { if (cleanMethod != null) { try { cleanMethod.invoke(cleanerMethod.invoke(buf)); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException e) { logger.warn("Error while cleaning up the DirectBuffer", e); } } else if (invokeCleanerMethod != null) { try { invokeCleanerMethod.invoke(unsafe, buf); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException e) { logger.warn("Error while cleaning up the DirectBuffer", e); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy