使用Apache Arrow C ++ API读取CSV时如何管理内存?

问题描述

我不了解C ++ Arrow API中的内存管理。我使用Arrow 1.0.0,正在读取CSV文件。运行ReadArrowTableFromCSV后,我的内存中已充满了已分配的数据。我想念什么吗?如何释放内存?我在内存池中看不到任何方法来清除所有分配的内存。下面的代码清单。

void LoadCSVData::ReadArrowTableFromCSV( const std::string & filePath )
{
    auto tableReader = CreateTableReader( filePath );
    ReadArrowTableusingReader( *tableReader );
}

std::shared_ptr<arrow::csv::TableReader> LoadCSVData::CreateTableReader( const std::string & filePath )
{
    arrow::MemoryPool* pool = arrow::default_memory_pool();
    auto tableReader = arrow::csv::TableReader::Make( pool,OpenCSVFile( filePath ),*PrepareReadOptions(),*PrepareParSEOptions(),*PrepareConvertOptions() );
    if ( !tableReader.ok() )
    {
        throw BadParametersException( std::string( "CSV file reader error: " ) + tableReader.status().ToString() );
    }
    return *tableReader;
}

void LoadCSVData::ReadArrowTableusingReader( arrow::csv::TableReader & reader )
{
    auto table = reader.Read();
    if ( !table.ok() )
    {
        throw BadParametersException( std::string( "CSV file reader error: " ) + table.status().ToString() );
    }
    this->mArrowTable = *table;
}

std::unique_ptr<arrow::csv::ParSEOptions> LoadCSVData::PrepareParSEOptions()
{
    auto parSEOptions = std::make_unique<arrow::csv::ParSEOptions>( arrow::csv::ParSEOptions::Defaults() );
    parSEOptions->delimiter = mDelimiter;
    return parSEOptions;
}

std::unique_ptr<arrow::csv::ReadOptions> LoadCSVData::PrepareReadOptions()
{
    auto readOptions = std::make_unique<arrow::csv::ReadOptions>( arrow::csv::ReadOptions::Defaults() );
    readOptions->skip_rows = mNumberOfheaderRows;
    readOptions->block_size = 1 << 27;  // 128 MB
    readOptions->column_names.reserve( mTable->GetNumberOfColumns() );

    for ( auto & colName : mTable->GetColumnsOrder() )
    {
        readOptions->column_names.emplace_back( colName );
    }

    return readOptions;
}

std::unique_ptr<arrow::csv::ConvertOptions> LoadCSVData::PrepareConvertOptions() const
{
    auto convertOptions = std::make_unique<arrow::csv::ConvertOptions>( arrow::csv::ConvertOptions::Defaults() );
    for ( auto & col : mTable->GetColumsInfo() )
    {
        convertOptions->column_types[col.second.GetName()] = MyTypetoArrowDataType( col.second.GetType() );
    }
    convertOptions->strings_can_be_null = true;

    return convertOptions;
}

std::shared_ptr<arrow::io::ReadableFile> LoadCSVData::OpenCSVFile( const std::string & filePath )
{
    MTR_ScopE_FUNC();
    auto inputFileResult = arrow::io::ReadableFile::Open( filePath );
    if ( !inputFileResult.ok() )
    {
        throw BadParametersException( std::string( "CSV file reader error: " ) + inputFileResult.status().ToString() );
    }
    return *inputFileResult;
}

解决方法

Maciej,方法TableReader::Read应该返回shared_ptr<arrow::Table>arrow::Table本身具有许多指向最终包含数据的结构的共享指针。要释放数据,您需要确保arrow::Table及其任何副本均已销毁。一旦shared_ptr超出范围,就会发生这种情况。但是,您似乎将表存储在此处的成员变量中(这是预期的,您可能希望在读取数据后使用数据):

this->mArrowTable = *table;

因此,现在您有了arrow::Table实例的第二个副本。您可以将this->mArrowTable重新分配给新的空白表,也可以销毁任何this。当然,如果要创建该表的其他任何副本,则还需要确保这些副本不在范围之内。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...